mirror of
https://github.com/lxsang/antd-lua-plugin
synced 2025-07-15 13:29:45 +02:00
mimgrating from another repo
This commit is contained in:
337
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/BinaryFile.pm
Executable file
337
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/BinaryFile.pm
Executable file
@ -0,0 +1,337 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::BinaryFile
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to manage Natural Docs' binary data files.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# - Only one data file can be managed with this package at a time. You must close the file before opening another
|
||||
# one.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::BinaryFile;
|
||||
|
||||
use vars qw(@EXPORT @ISA);
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT = ('BINARY_FORMAT');
|
||||
|
||||
use Encode qw(encode_utf8 decode_utf8);
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Format
|
||||
|
||||
#
|
||||
# Topic: Standard Header
|
||||
#
|
||||
# > [UInt8: BINARY_FORMAT]
|
||||
# > [VersionInt: app version]
|
||||
#
|
||||
# The first byte is <BINARY_FORMAT>, which distinguishes binary configuration files from text ones, since Natural Docs
|
||||
# used to use text data files with the same name.
|
||||
#
|
||||
# The next section is the version of Natural Docs that wrote the file, as defined by <NaturalDocs::Settings->AppVersion>
|
||||
# and written by <NaturalDocs::Version->ToBinaryFile()>.
|
||||
#
|
||||
|
||||
#
|
||||
# Topic: Data Types
|
||||
#
|
||||
# All the integer data types are written most significant byte first, aka big endian.
|
||||
#
|
||||
# An AString16 is a UInt16 followed by that many 8-bit ASCII characters. It doesn't include a null character at the end. Undef
|
||||
# strings are represented by a zero for the UInt16 and nothing following it.
|
||||
#
|
||||
# A UString16 is a UInt16 followed by that many UTF-8 encoded bytes. It doesn't include a null character at the end. Undef
|
||||
# strings are represented by a zero for the UInt16 and nothing following it.
|
||||
#
|
||||
|
||||
#
|
||||
# Constant: BINARY_FORMAT
|
||||
#
|
||||
# An 8-bit constant that's used as the first byte of binary data files. This is used so that you can easily distinguish between
|
||||
# binary and old-style text data files. It's not a character that would appear in plain text files.
|
||||
#
|
||||
use constant BINARY_FORMAT => pack('C', 0x06);
|
||||
# Which is ACK or acknowledge in ASCII. Is the cool spade character in DOS displays.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
#
|
||||
# handle: FH_BINARYDATAFILE
|
||||
#
|
||||
# The file handle used for the data file.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# string: currentFile
|
||||
#
|
||||
# The <FileName> for the current configuration file being parsed.
|
||||
#
|
||||
my $currentFile;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: File Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: OpenForReading
|
||||
#
|
||||
# Opens a binary file for reading.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# minimumVersion - The minimum version of the file format that is acceptible. May be undef.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The format <VersionInt> or undef if it failed. It could fail for any of the following reasons.
|
||||
#
|
||||
# - The file doesn't exist.
|
||||
# - The file couldn't be opened.
|
||||
# - The file didn't have the proper header.
|
||||
# - Either the application or the file was from a development release, and they're not the exact same development release.
|
||||
# - The file's format was less than the minimum version, if one was defined.
|
||||
# - The file was from a later application version than the current.
|
||||
#
|
||||
sub OpenForReading #(FileName file, optional VersionInt minimumVersion) => VersionInt
|
||||
{
|
||||
my ($self, $file, $minimumVersion) = @_;
|
||||
|
||||
if (defined $currentFile)
|
||||
{ die "Tried to open binary file " . $file . " for reading when " . $currentFile . " was already open."; };
|
||||
|
||||
$currentFile = $file;
|
||||
|
||||
if (open(FH_BINARYDATAFILE, '<' . $currentFile))
|
||||
{
|
||||
# See if it's binary.
|
||||
binmode(FH_BINARYDATAFILE);
|
||||
|
||||
my $firstChar;
|
||||
read(FH_BINARYDATAFILE, $firstChar, 1);
|
||||
|
||||
if ($firstChar == ::BINARY_FORMAT())
|
||||
{
|
||||
my $version = NaturalDocs::Version->FromBinaryFile(\*FH_BINARYDATAFILE);
|
||||
|
||||
if (NaturalDocs::Version->CheckFileFormat($version, $minimumVersion))
|
||||
{ return $version; };
|
||||
};
|
||||
|
||||
close(FH_BINARYDATAFILE);
|
||||
};
|
||||
|
||||
$currentFile = undef;
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OpenForWriting
|
||||
#
|
||||
# Opens a binary file for writing and writes the standard header. Dies if the file cannot be opened.
|
||||
#
|
||||
sub OpenForWriting #(FileName file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $currentFile)
|
||||
{ die "Tried to open binary file " . $file . " for writing when " . $currentFile . " was already open."; };
|
||||
|
||||
$currentFile = $file;
|
||||
|
||||
open (FH_BINARYDATAFILE, '>' . $currentFile)
|
||||
or die "Couldn't save " . $file . ".\n";
|
||||
|
||||
binmode(FH_BINARYDATAFILE);
|
||||
|
||||
print FH_BINARYDATAFILE '' . ::BINARY_FORMAT();
|
||||
NaturalDocs::Version->ToBinaryFile(\*FH_BINARYDATAFILE, NaturalDocs::Settings->AppVersion());
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Close
|
||||
#
|
||||
# Closes the current configuration file.
|
||||
#
|
||||
sub Close
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (!$currentFile)
|
||||
{ die "Tried to close a binary file when one wasn't open."; };
|
||||
|
||||
close(FH_BINARYDATAFILE);
|
||||
$currentFile = undef;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Reading Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: GetUInt8
|
||||
# Reads and returns a UInt8 from the open file.
|
||||
#
|
||||
sub GetUInt8 # => UInt8
|
||||
{
|
||||
my $raw;
|
||||
read(FH_BINARYDATAFILE, $raw, 1);
|
||||
|
||||
return unpack('C', $raw);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: GetUInt16
|
||||
# Reads and returns a UInt16 from the open file.
|
||||
#
|
||||
sub GetUInt16 # => UInt16
|
||||
{
|
||||
my $raw;
|
||||
read(FH_BINARYDATAFILE, $raw, 2);
|
||||
|
||||
return unpack('n', $raw);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: GetUInt32
|
||||
# Reads and returns a UInt32 from the open file.
|
||||
#
|
||||
sub GetUInt32 # => UInt32
|
||||
{
|
||||
my $raw;
|
||||
read(FH_BINARYDATAFILE, $raw, 4);
|
||||
|
||||
return unpack('N', $raw);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: GetAString16
|
||||
# Reads and returns an AString16 from the open file. Supports undef strings.
|
||||
#
|
||||
sub GetAString16 # => string
|
||||
{
|
||||
my $rawLength;
|
||||
read(FH_BINARYDATAFILE, $rawLength, 2);
|
||||
my $length = unpack('n', $rawLength);
|
||||
|
||||
if (!$length)
|
||||
{ return undef; };
|
||||
|
||||
my $string;
|
||||
read(FH_BINARYDATAFILE, $string, $length);
|
||||
|
||||
return $string;
|
||||
};
|
||||
|
||||
#
|
||||
# Function: GetUString16
|
||||
# Reads and returns a UString16 from the open file. Supports undef strings.
|
||||
#
|
||||
sub GetUString16 # => string
|
||||
{
|
||||
my $rawLength;
|
||||
read(FH_BINARYDATAFILE, $rawLength, 2);
|
||||
my $length = unpack('n', $rawLength);
|
||||
|
||||
if (!$length)
|
||||
{ return undef; };
|
||||
|
||||
my $string;
|
||||
read(FH_BINARYDATAFILE, $string, $length);
|
||||
$string = decode_utf8($string);
|
||||
|
||||
return $string;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Writing Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: WriteUInt8
|
||||
# Writes a UInt8 to the open file.
|
||||
#
|
||||
sub WriteUInt8 #(UInt8 value)
|
||||
{
|
||||
my ($self, $value) = @_;
|
||||
print FH_BINARYDATAFILE pack('C', $value);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: WriteUInt16
|
||||
# Writes a UInt32 to the open file.
|
||||
#
|
||||
sub WriteUInt16 #(UInt16 value)
|
||||
{
|
||||
my ($self, $value) = @_;
|
||||
print FH_BINARYDATAFILE pack('n', $value);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: WriteUInt32
|
||||
# Writes a UInt32 to the open file.
|
||||
#
|
||||
sub WriteUInt32 #(UInt32 value)
|
||||
{
|
||||
my ($self, $value) = @_;
|
||||
print FH_BINARYDATAFILE pack('N', $value);
|
||||
};
|
||||
|
||||
#
|
||||
# Function: WriteAString16
|
||||
# Writes an AString16 to the open file. Supports undef strings.
|
||||
#
|
||||
sub WriteAString16 #(string value)
|
||||
{
|
||||
my ($self, $string) = @_;
|
||||
|
||||
if (length($string))
|
||||
{ print FH_BINARYDATAFILE pack('nA*', length($string), $string); }
|
||||
else
|
||||
{ print FH_BINARYDATAFILE pack('n', 0); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: WriteUString16
|
||||
# Writes an UString16 to the open file. Supports undef strings.
|
||||
#
|
||||
sub WriteUString16 #(string value)
|
||||
{
|
||||
my ($self, $string) = @_;
|
||||
|
||||
if (length($string))
|
||||
{
|
||||
$string = encode_utf8($string);
|
||||
print FH_BINARYDATAFILE pack('na*', length($string), $string);
|
||||
}
|
||||
else
|
||||
{ print FH_BINARYDATAFILE pack('n', 0); };
|
||||
};
|
||||
|
||||
|
||||
1;
|
281
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder.pm
Executable file
281
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder.pm
Executable file
@ -0,0 +1,281 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Builder
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package that takes parsed source file and builds the output for it.
|
||||
#
|
||||
# Usage and Dependencies:
|
||||
#
|
||||
# - <Add()> can be called immediately.
|
||||
# - <OutputPackages()> and <OutputPackageOf()> can be called once all sub-packages have been registered via <Add()>.
|
||||
# Since this is normally done in their INIT functions, they should be available to all normal functions immediately.
|
||||
#
|
||||
# - Prior to calling <Run()>, <NaturalDocs::Settings>, <NaturalDocs::Project>, <NaturalDocs::Menu>, and
|
||||
# <NaturalDocs::Parser> must be initialized. <NaturalDocs::Settings->GenerateDirectoryNames()> must be called.
|
||||
# <NaturalDocs::SymbolTable> and <NaturalDocs::ClassHierarchy> must be initialized and fully resolved.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use NaturalDocs::Builder::Base;
|
||||
use NaturalDocs::Builder::HTML;
|
||||
use NaturalDocs::Builder::FramedHTML;
|
||||
|
||||
package NaturalDocs::Builder;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
#
|
||||
# Array: outputPackages
|
||||
#
|
||||
# An array of the output packages available for use.
|
||||
#
|
||||
my @outputPackages;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: OutputPackages
|
||||
#
|
||||
# Returns an arrayref of the output packages available for use. The arrayref is not a copy of the data, so don't change it.
|
||||
#
|
||||
# Add output packages to this list with the <Add()> function.
|
||||
#
|
||||
sub OutputPackages
|
||||
{ return \@outputPackages; };
|
||||
|
||||
|
||||
#
|
||||
# Function: OutputPackageOf
|
||||
#
|
||||
# Returns the output package corresponding to the passed command line option, or undef if none.
|
||||
#
|
||||
sub OutputPackageOf #(commandLineOption)
|
||||
{
|
||||
my ($self, $commandLineOption) = @_;
|
||||
|
||||
$commandLineOption = lc($commandLineOption);
|
||||
|
||||
foreach my $package (@outputPackages)
|
||||
{
|
||||
if (lc($package->CommandLineOption()) eq $commandLineOption)
|
||||
{ return $package; };
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Function: Add
|
||||
#
|
||||
# Adds an output package to those available for use. All output packages must call this function in order to be recognized.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# package - The package name.
|
||||
#
|
||||
sub Add #(package)
|
||||
{
|
||||
my ($self, $package) = @_;
|
||||
|
||||
# Output packages shouldn't register themselves more than once, so we don't need to check for it.
|
||||
push @outputPackages, $package;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Run
|
||||
#
|
||||
# Runs the build process. This must be called *every time* Natural Docs is run, regardless of whether any source files changed
|
||||
# or not. Some output packages have dependencies on files outside of the source tree that need to be checked.
|
||||
#
|
||||
# Since there are multiple stages to the build process, this function will handle its own status messages. There's no need to print
|
||||
# "Building files..." or something similar beforehand.
|
||||
#
|
||||
sub Run
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
|
||||
# Determine what we're doing.
|
||||
|
||||
my $buildTargets = NaturalDocs::Settings->BuildTargets();
|
||||
|
||||
my $filesToBuild = NaturalDocs::Project->FilesToBuild();
|
||||
my $numberOfFilesToBuild = (scalar keys %$filesToBuild) * (scalar @$buildTargets);
|
||||
|
||||
my $filesToPurge = NaturalDocs::Project->FilesToPurge();
|
||||
my $numberOfFilesToPurge = (scalar keys %$filesToPurge) * (scalar @$buildTargets);
|
||||
|
||||
my $imagesToUpdate = NaturalDocs::Project->ImageFilesToUpdate();
|
||||
my $numberOfImagesToUpdate = (scalar keys %$imagesToUpdate) * (scalar @$buildTargets);
|
||||
|
||||
my $imagesToPurge = NaturalDocs::Project->ImageFilesToPurge();
|
||||
my $numberOfImagesToPurge = (scalar keys %$imagesToPurge) * (scalar @$buildTargets);
|
||||
|
||||
my %indexesToBuild;
|
||||
my %indexesToPurge;
|
||||
|
||||
my $currentIndexes = NaturalDocs::Menu->Indexes();
|
||||
my $previousIndexes = NaturalDocs::Menu->PreviousIndexes();
|
||||
|
||||
foreach my $index (keys %$currentIndexes)
|
||||
{
|
||||
if (NaturalDocs::SymbolTable->IndexChanged($index) || !exists $previousIndexes->{$index})
|
||||
{
|
||||
$indexesToBuild{$index} = 1;
|
||||
};
|
||||
};
|
||||
|
||||
# All indexes that still exist should have been deleted.
|
||||
foreach my $index (keys %$previousIndexes)
|
||||
{
|
||||
if (!exists $currentIndexes->{$index})
|
||||
{
|
||||
$indexesToPurge{$index} = 1;
|
||||
};
|
||||
};
|
||||
|
||||
my $numberOfIndexesToBuild = (scalar keys %indexesToBuild) * (scalar @$buildTargets);
|
||||
my $numberOfIndexesToPurge = (scalar keys %indexesToPurge) * (scalar @$buildTargets);
|
||||
|
||||
|
||||
# Start the build process
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->BeginBuild( $numberOfFilesToBuild || $numberOfFilesToPurge ||
|
||||
$numberOfImagesToUpdate || $numberOfImagesToPurge ||
|
||||
$numberOfIndexesToBuild || $numberOfIndexesToPurge ||
|
||||
NaturalDocs::Menu->HasChanged() );
|
||||
};
|
||||
|
||||
if ($numberOfFilesToPurge)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Purging ' . $numberOfFilesToPurge
|
||||
. ' file' . ($numberOfFilesToPurge > 1 ? 's' : '') . '...',
|
||||
scalar @$buildTargets);
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->PurgeFiles($filesToPurge);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
};
|
||||
|
||||
if ($numberOfIndexesToPurge)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Purging ' . $numberOfIndexesToPurge
|
||||
. ' index' . ($numberOfIndexesToPurge > 1 ? 'es' : '') . '...',
|
||||
scalar @$buildTargets);
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->PurgeIndexes(\%indexesToPurge);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
};
|
||||
|
||||
if ($numberOfImagesToPurge)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Purging ' . $numberOfImagesToPurge
|
||||
. ' image' . ($numberOfImagesToPurge > 1 ? 's' : '') . '...',
|
||||
scalar @$buildTargets);
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->PurgeImages($imagesToPurge);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
};
|
||||
|
||||
if ($numberOfFilesToBuild)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Building ' . $numberOfFilesToBuild
|
||||
. ' file' . ($numberOfFilesToBuild > 1 ? 's' : '') . '...',
|
||||
$numberOfFilesToBuild);
|
||||
|
||||
foreach my $file (keys %$filesToBuild)
|
||||
{
|
||||
my $parsedFile = NaturalDocs::Parser->ParseForBuild($file);
|
||||
|
||||
NaturalDocs::Error->OnStartBuilding($file);
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->BuildFile($file, $parsedFile);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
|
||||
NaturalDocs::Error->OnEndBuilding($file);
|
||||
};
|
||||
};
|
||||
|
||||
if ($numberOfIndexesToBuild)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Building ' . $numberOfIndexesToBuild
|
||||
. ' index' . ($numberOfIndexesToBuild > 1 ? 'es' : '') . '...',
|
||||
$numberOfIndexesToBuild);
|
||||
|
||||
foreach my $index (keys %indexesToBuild)
|
||||
{
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->BuildIndex($index);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if ($numberOfImagesToUpdate)
|
||||
{
|
||||
NaturalDocs::StatusMessage->Start('Updating ' . $numberOfImagesToUpdate
|
||||
. ' image' . ($numberOfImagesToUpdate > 1 ? 's' : '') . '...',
|
||||
$numberOfImagesToUpdate);
|
||||
|
||||
foreach my $image (keys %$imagesToUpdate)
|
||||
{
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->UpdateImage($image);
|
||||
NaturalDocs::StatusMessage->CompletedItem();
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (NaturalDocs::Menu->HasChanged())
|
||||
{
|
||||
if (!NaturalDocs::Settings->IsQuiet())
|
||||
{ print "Updating menu...\n"; };
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{ $buildTarget->Builder()->UpdateMenu(); };
|
||||
};
|
||||
|
||||
foreach my $buildTarget (@$buildTargets)
|
||||
{
|
||||
$buildTarget->Builder()->EndBuild($numberOfFilesToBuild || $numberOfFilesToPurge ||
|
||||
$numberOfIndexesToBuild || $numberOfIndexesToPurge ||
|
||||
$numberOfImagesToUpdate || $numberOfImagesToPurge ||
|
||||
NaturalDocs::Menu->HasChanged());
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
349
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/Base.pm
Executable file
349
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/Base.pm
Executable file
@ -0,0 +1,349 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Builder::Base
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A base class for all Builder output formats.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Builder::Base;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Notes
|
||||
|
||||
|
||||
#
|
||||
# Topic: Implementation
|
||||
#
|
||||
# Builder packages are implemented as blessed arrayrefs, not hashrefs. This is done for all objects in Natural Docs for
|
||||
# efficiency reasons. You create members by defining constants via <NaturalDocs::DefineMembers> and using them as
|
||||
# indexes into the array.
|
||||
#
|
||||
|
||||
#
|
||||
# Topic: Function Order
|
||||
#
|
||||
# The functions in the build process will always be called in the following order.
|
||||
#
|
||||
# - <BeginBuild()> will always be called.
|
||||
# - <PurgeFiles()> will be called next only if there's files that need to be purged.
|
||||
# - <PurgeIndexes()> will be called next only if there's indexes that need to be purged.
|
||||
# - <PurgeImages()> will e called next only if there's images that need to be purged.
|
||||
# - <BuildFile()> will be called once for each file that needs to be built, if any.
|
||||
# - <BuildIndex()> will be called once for each index that changed and is part of the menu, if any.
|
||||
# - <UpdateImage()> will be called once for each image that needs to be updated, if any.
|
||||
# - <UpdateMenu()> will be called next only if the menu changed.
|
||||
# - <EndBuild()> will always be called.
|
||||
#
|
||||
|
||||
#
|
||||
# Topic: How to Approach
|
||||
#
|
||||
# Here's an idea of how to approach making packages for different output types.
|
||||
#
|
||||
#
|
||||
# Multiple Output Files, Embedded Menu:
|
||||
#
|
||||
# This example is for when you want to build one output file per source file, each with its own copy of the menu within it.
|
||||
# This is how <NaturalDocs::Builder::HTML> works.
|
||||
#
|
||||
# Make sure you create a function that generates just the menu for a particular source file. We'll need to generate menus for
|
||||
# both building a file from scratch and for updating the menu on an existing output file, so it's better to give it its own function.
|
||||
# You may want to surround it with something that can be easily detected in the output file to make replacing easier.
|
||||
#
|
||||
# <BeginBuild()> isn't important. You don't need to implement it.
|
||||
#
|
||||
# Implement <PurgeFiles()> to delete the output files associated with the purged files.
|
||||
#
|
||||
# Implement <PurgeIndexes()> to delete the output files associated with the purged indexes.
|
||||
#
|
||||
# Implement <BuildFile()> to create an output file for the parsed source file. Use the menu function described earlier.
|
||||
#
|
||||
# Implement <BuildIndex()> to create an output file for each index. Use the menu function described earlier for each page.
|
||||
#
|
||||
# Implement <UpdateMenu()> to go through the list of unbuilt files and update their menus. You can get the list from
|
||||
# <NaturalDocs::Project->UnbuiltFilesWithContent()>. You need to open their output files, replace the menu, and save it back
|
||||
# to disk. Yes, it would be simpler from a programmer's point of view to just rebuild the file completely, but that would be
|
||||
# _very_ inefficient since there could potentially be a _lot_ of files in this group.
|
||||
#
|
||||
# Also make sure <UpdateMenu()> goes through the unchanged indexes and updates them as well.
|
||||
#
|
||||
# <EndBuild()> isn't important. You don't need to implement it.
|
||||
#
|
||||
#
|
||||
# Multiple Output Files, Menu in File:
|
||||
#
|
||||
# This example is for when you want to build one output file per source file, but keep the menu in its own separate file. This
|
||||
# is how <NaturalDocs::Builder::FramedHTML> works.
|
||||
#
|
||||
# <BeginBuild()> isn't important. You don't need to implement it.
|
||||
#
|
||||
# Implement <PurgeFiles()> to delete the output files associated with the purged files.
|
||||
#
|
||||
# Implement <PurgeIndexes()> to delete the output files associated with the purged indexes.
|
||||
#
|
||||
# Implement <BuildFile()> to generate an output file from the parsed source file.
|
||||
#
|
||||
# Implement <BuildIndex()> to generate an output file for each index.
|
||||
#
|
||||
# Implement <UpdateMenu()> to rebuild the menu file.
|
||||
#
|
||||
# <EndBuild()> isn't important. You don't need to implement it.
|
||||
#
|
||||
#
|
||||
# Single Output File using Intermediate Files:
|
||||
#
|
||||
# This example is for when you want to build one output file, such as a PDF file, but use intermediate files to handle differential
|
||||
# building. This would be much like how a compiler compiles each source file into a object file, and then a linker stitches them
|
||||
# all together into the final executable file.
|
||||
#
|
||||
# <BeginBuild()> isn't important. You don't need to implement it.
|
||||
#
|
||||
# Implement <PurgeFiles()> to delete the intermediate files associated with the purged files.
|
||||
#
|
||||
# Implement <PurgeIndexes()> to delete the intermediate files associated with the purged indexes.
|
||||
#
|
||||
# Implement <BuildFile()> to generate an intermediate file from the parsed source file.
|
||||
#
|
||||
# Implement <BuildIndex()> to generate an intermediate file for the specified index.
|
||||
#
|
||||
# Implement <UpdateMenu()> to generate the intermediate file for the menu.
|
||||
#
|
||||
# Implement <EndBuild()> so that if the project changed, it stitches the intermediate files together into the final
|
||||
# output file. Make sure you check the parameter because the function will be called when nothing changes too.
|
||||
#
|
||||
#
|
||||
# Single Output File using Direct Changes:
|
||||
#
|
||||
# This example is for when you want to build one output file, such as a PDF file, but engineering it in such a way that you don't
|
||||
# need to use intermediate files. In other words, you're able to add, delete, and modify entries directly in the output file.
|
||||
#
|
||||
# Implement <BeginBuild()> so that if the project changed, it opens the output file and does anything it needs to do
|
||||
# to get ready for editing.
|
||||
#
|
||||
# Implement <PurgeFiles()> to remove the entries associated with the purged files.
|
||||
#
|
||||
# Implement <PurgeIndexes()> to remove the entries associated with the purged indexes.
|
||||
#
|
||||
# Implement <BuildFile()> to add or replace a section of the output file with a new one generated from the parsed file.
|
||||
#
|
||||
# Implement <BuildIndex()> to add or replace an index in the output file with a new one generated from the specified index.
|
||||
#
|
||||
# Implement <EndBuild()> so that if the project changed, it saves the output file to disk.
|
||||
#
|
||||
# How you handle the menu depends on how the output file references other sections of itself. If it can do so by name, then
|
||||
# you can implement <UpdateMenu()> to update the menu section of the file and you're done. If it has to reference itself
|
||||
# by address or offset, it gets trickier. You should skip <UpdateMenu()> and instead rebuild the menu in <EndBuild()> if
|
||||
# the parameter is true. This lets you do it whenever anything changes in a file, rather than just when the menu
|
||||
# visibly changes. How you keep track of the locations and how they change is your problem.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Group: Required Interface Functions
|
||||
#
|
||||
# All Builder classes *must* define these functions.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: INIT
|
||||
#
|
||||
# Define this function to call <NaturalDocs::Builder->Add()> so that <NaturalDocs::Builder> knows about this package.
|
||||
# Packages are defined this way so that new ones can be added without messing around in other code.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: CommandLineOption
|
||||
#
|
||||
# Define this function to return the text that should be put in the command line after -o to use this package. It cannot have
|
||||
# spaces and is not case sensitive.
|
||||
#
|
||||
# For example, <NaturalDocs::Builder::HTML> returns 'html' so someone could use -o html [directory] to use that package.
|
||||
#
|
||||
sub CommandLineOption
|
||||
{
|
||||
NaturalDocs::Error->SoftDeath($_[0] . " didn't define CommandLineOption().");
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildFile
|
||||
#
|
||||
# Define this function to convert a parsed file to this package's output format. This function will be called once for every source
|
||||
# file that needs to be rebuilt. However, if a file hasn't changed since the last time Natural Docs was run, it will not be sent to
|
||||
# this function. All packages must support differential build.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The name of the source file.
|
||||
# parsedFile - The parsed source file, as an arrayref of <NaturalDocs::Parser::ParsedTopic> objects.
|
||||
#
|
||||
sub BuildFile #(sourceFile, parsedFile)
|
||||
{
|
||||
NaturalDocs::Error->SoftDeath($_[0] . " didn't define BuildFile().");
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Group: Optional Interface Functions
|
||||
#
|
||||
# These functions can be implemented but packages are not required to do so.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Note that this is the only function where the first parameter will be the package name, not the object itself.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BeginBuild
|
||||
#
|
||||
# Define this function if the package needs to do anything at the beginning of the build process. This function will be called
|
||||
# every time Natural Docs is run, even if the project hasn't changed. This allows you to manage dependencies specific
|
||||
# to the output format that may change independently from the source tree and menu. For example,
|
||||
# <NaturalDocs::Builder::HTML> needs to keep the CSS files in sync regardless of whether the source tree changed or not.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# hasChanged - Whether the project has changed, such as source files or the menu file. If false, nothing else is going to be
|
||||
# called except <EndBuild()>.
|
||||
#
|
||||
sub BeginBuild #(hasChanged)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: EndBuild
|
||||
#
|
||||
# Define this function if the package needs to do anything at the end of the build process. This function will be called every time
|
||||
# Natural Docs is run, even if the project hasn't changed. This allows you to manage dependencies specific to the output
|
||||
# format that may change independently from the source tree. For example, <NaturalDocs::Builder::HTML> needs to keep the
|
||||
# CSS files in sync regardless of whether the source tree changed or not.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# hasChanged - Whether the project has changed, such as source files or the menu file. If false, the only other function that
|
||||
# was called was <BeginBuild()>.
|
||||
#
|
||||
sub EndBuild #(hasChanged)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildIndex
|
||||
#
|
||||
# Define this function to create an index for the passed topic. You can get the index from
|
||||
# <NaturalDocs::SymbolTable->Index()>.
|
||||
#
|
||||
# The reason it's not passed directly to this function is because indexes may be time-consuming to create. As such, they're
|
||||
# generated on demand because some output packages may choose not to implement them.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# topic - The <TopicType> to limit the index by.
|
||||
#
|
||||
sub BuildIndex #(topic)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateImage
|
||||
#
|
||||
# Define this function to add or update the passed image in the output.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The image <FileName>
|
||||
#
|
||||
sub UpdateImage #(file)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PurgeFiles
|
||||
#
|
||||
# Define this function to make the package remove all output related to the passed files. These files no longer have Natural Docs
|
||||
# content.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# files - An existence hashref of the files to purge.
|
||||
#
|
||||
sub PurgeFiles #(files)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PurgeIndexes
|
||||
#
|
||||
# Define this function to make the package remove all output related to the passed indexes. These indexes are no longer part
|
||||
# of the menu.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# indexes - An existence hashref of the <TopicTypes> of the indexes to purge.
|
||||
#
|
||||
sub PurgeIndexes #(indexes)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PurgeImages
|
||||
#
|
||||
# Define this function to make the package remove all output related to the passed image files. These files are no longer used
|
||||
# by the documentation.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# files - An existence hashref of the image <FileNames> to purge.
|
||||
#
|
||||
sub PurgeImages #(files)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateMenu
|
||||
#
|
||||
# Define this function to make the package update the menu. It will only be called if the menu changed.
|
||||
#
|
||||
sub UpdateMenu
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
1;
|
354
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/FramedHTML.pm
Executable file
354
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/FramedHTML.pm
Executable file
@ -0,0 +1,354 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Builder::FramedHTML
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package that generates output in HTML with frames.
|
||||
#
|
||||
# All functions are called with Package->Function() notation.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Builder::FramedHTML;
|
||||
|
||||
use base 'NaturalDocs::Builder::HTMLBase';
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implemented Interface Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: INIT
|
||||
#
|
||||
# Registers the package with <NaturalDocs::Builder>.
|
||||
#
|
||||
sub INIT
|
||||
{
|
||||
NaturalDocs::Builder->Add(__PACKAGE__);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CommandLineOption
|
||||
#
|
||||
# Returns the option to follow -o to use this package. In this case, "html".
|
||||
#
|
||||
sub CommandLineOption
|
||||
{
|
||||
return 'FramedHTML';
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildFile
|
||||
#
|
||||
# Builds the output file from the parsed source file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourcefile - The <FileName> of the source file.
|
||||
# parsedFile - An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
|
||||
#
|
||||
sub BuildFile #(sourceFile, parsedFile)
|
||||
{
|
||||
my ($self, $sourceFile, $parsedFile) = @_;
|
||||
|
||||
my $outputFile = $self->OutputFileOf($sourceFile);
|
||||
|
||||
|
||||
# 99.99% of the time the output directory will already exist, so this will actually be more efficient. It only won't exist
|
||||
# if a new file was added in a new subdirectory and this is the first time that file was ever parsed.
|
||||
if (!open(OUTPUTFILEHANDLE, '>' . $outputFile))
|
||||
{
|
||||
NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) );
|
||||
|
||||
open(OUTPUTFILEHANDLE, '>' . $outputFile)
|
||||
or die "Couldn't create output file " . $outputFile . "\n";
|
||||
};
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
my $usePrettify = (NaturalDocs::Settings->HighlightCode() || NaturalDocs::Settings->HighlightAnonymous());
|
||||
|
||||
|
||||
print OUTPUTFILEHANDLE
|
||||
|
||||
# IE 6 doesn't like any doctype here at all. Add one (strict or transitional doesn't matter) and it makes the page slightly too
|
||||
# wide for the frame. Mozilla and Opera handle it like champs either way because they Don't Suck(tm).
|
||||
|
||||
# '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
|
||||
# . '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
|
||||
|
||||
'<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>'
|
||||
. $self->BuildTitle($sourceFile)
|
||||
. '</title>'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '"></script>';
|
||||
|
||||
if ($usePrettify)
|
||||
{
|
||||
print OUTPUTFILEHANDLE
|
||||
'<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->PrettifyJavaScriptFile(), 1) . '">'
|
||||
. '</script>';
|
||||
}
|
||||
|
||||
print OUTPUTFILEHANDLE
|
||||
'</head><body class="FramedContentPage" onLoad="NDOnLoad();' . ($usePrettify ? 'prettyPrint();' : '') . '">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->BuildContent($sourceFile, $parsedFile)
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->BuildToolTips()
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
. '</body></html>';
|
||||
|
||||
|
||||
close(OUTPUTFILEHANDLE);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildIndex
|
||||
#
|
||||
# Builds an index for the passed type.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> to limit the index to, or undef if none.
|
||||
#
|
||||
sub BuildIndex #(type)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
my $indexTitle = $self->IndexTitleOf($type);
|
||||
my $indexFile = $self->IndexFileOf($type);
|
||||
|
||||
my $startIndexPage =
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>';
|
||||
|
||||
if (defined NaturalDocs::Menu->Title())
|
||||
{ $startIndexPage .= $self->StringToHTML(NaturalDocs::Menu->Title()) . ' - '; };
|
||||
|
||||
$startIndexPage .=
|
||||
$indexTitle
|
||||
. '</title>'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($indexFile, $self->MainCSSFile(), 1) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->MainJavaScriptFile(), 1) . '"></script>'
|
||||
|
||||
. '</head><body class="FramedIndexPage" onLoad="NDOnLoad()">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->StandardComments()
|
||||
. "\n\n\n"
|
||||
. '<div id=Index>'
|
||||
. '<div class=IPageTitle>'
|
||||
. $indexTitle
|
||||
. '</div>';
|
||||
|
||||
|
||||
my $endIndexPage =
|
||||
|
||||
'</div><!--Index-->'
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
|
||||
. '</body></html>';
|
||||
|
||||
my $startSearchResultsPage =
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($indexFile, $self->MainCSSFile(), 1) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->MainJavaScriptFile(), 1) . '"></script>'
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($indexFile, $self->SearchDataJavaScriptFile(), 1) . '">'
|
||||
. '</script>'
|
||||
|
||||
. '</head><body class="FramedSearchResultsPage" onLoad="NDOnLoad()">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->StandardComments()
|
||||
. "\n\n\n"
|
||||
|
||||
. '<div id=Index>'
|
||||
. '<div class=IPageTitle>'
|
||||
. 'Search Results'
|
||||
. '</div>';
|
||||
|
||||
my $endSearchResultsPage =
|
||||
|
||||
'</div><!--Index-->'
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
|
||||
. '</body></html>';
|
||||
|
||||
my $indexContent = NaturalDocs::SymbolTable->Index($type);
|
||||
my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage,
|
||||
$startSearchResultsPage, $endSearchResultsPage);
|
||||
$self->PurgeIndexFiles($type, $indexContent, $pageCount + 1);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateMenu
|
||||
#
|
||||
# Builds the menu file. Also generates index.html.
|
||||
#
|
||||
sub UpdateMenu
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
|
||||
my $outputFile = NaturalDocs::File->JoinPaths($outputDirectory, 'menu.html');
|
||||
|
||||
|
||||
open(OUTPUTFILEHANDLE, '>' . $outputFile)
|
||||
or die "Couldn't create output file " . $outputFile . "\n";
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
|
||||
my $title = 'Menu';
|
||||
if (defined $title)
|
||||
{ $title .= ' - ' . NaturalDocs::Menu->Title(); };
|
||||
|
||||
$title = $self->StringToHTML($title);
|
||||
|
||||
|
||||
print OUTPUTFILEHANDLE
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/loose.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>'
|
||||
. $title
|
||||
. '</title>'
|
||||
|
||||
. '<base target="Content">'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '"></script>'
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->SearchDataJavaScriptFile(), 1) . '">'
|
||||
. '</script>'
|
||||
|
||||
. '</head><body class="FramedMenuPage" onLoad="NDOnLoad()">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->BuildMenu(undef, undef)
|
||||
. "\n\n\n"
|
||||
. $self->BuildFooter(1)
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
. '</body></html>';
|
||||
|
||||
|
||||
close(OUTPUTFILEHANDLE);
|
||||
|
||||
|
||||
# Update index.html
|
||||
|
||||
my $firstMenuEntry = $self->FindFirstFile();
|
||||
my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' );
|
||||
|
||||
# We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu.
|
||||
if (defined $firstMenuEntry)
|
||||
{
|
||||
open(INDEXFILEHANDLE, '>' . $indexFile)
|
||||
or die "Couldn't create output file " . $indexFile . ".\n";
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
|
||||
print INDEXFILEHANDLE
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/frameset.dtd">'
|
||||
|
||||
. '<html>'
|
||||
|
||||
. '<head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>'
|
||||
. $self->StringToHTML(NaturalDocs::Menu->Title())
|
||||
. '</title>'
|
||||
|
||||
. '</head>'
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. '<frameset cols="185,*">'
|
||||
. '<frame name=Menu src="menu.html">'
|
||||
. '<frame name=Content src="'
|
||||
. $self->MakeRelativeURL($indexFile, $self->OutputFileOf($firstMenuEntry->Target()), 1) . '">'
|
||||
. '</frameset>'
|
||||
|
||||
. '<noframes>'
|
||||
. 'This documentation was designed for use with frames. However, you can still use it by '
|
||||
. '<a href="menu.html">starting from the menu page</a>.'
|
||||
. "<script language=JavaScript><!--\n"
|
||||
. 'location.href="menu.html";'
|
||||
. "\n// --></script>"
|
||||
. '</noframes>'
|
||||
|
||||
. '</html>';
|
||||
|
||||
close INDEXFILEHANDLE;
|
||||
}
|
||||
|
||||
elsif (-e $indexFile)
|
||||
{
|
||||
unlink($indexFile);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
414
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTML.pm
Executable file
414
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTML.pm
Executable file
@ -0,0 +1,414 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Builder::HTML
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package that generates output in HTML.
|
||||
#
|
||||
# All functions are called with Package->Function() notation.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Builder::HTML;
|
||||
|
||||
use base 'NaturalDocs::Builder::HTMLBase';
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implemented Interface Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: INIT
|
||||
#
|
||||
# Registers the package with <NaturalDocs::Builder>.
|
||||
#
|
||||
sub INIT
|
||||
{
|
||||
NaturalDocs::Builder->Add(__PACKAGE__);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CommandLineOption
|
||||
#
|
||||
# Returns the option to follow -o to use this package. In this case, "html".
|
||||
#
|
||||
sub CommandLineOption
|
||||
{
|
||||
return 'HTML';
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildFile
|
||||
#
|
||||
# Builds the output file from the parsed source file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourcefile - The <FileName> of the source file.
|
||||
# parsedFile - An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
|
||||
#
|
||||
sub BuildFile #(sourceFile, parsedFile)
|
||||
{
|
||||
my ($self, $sourceFile, $parsedFile) = @_;
|
||||
|
||||
my $outputFile = $self->OutputFileOf($sourceFile);
|
||||
|
||||
|
||||
# 99.99% of the time the output directory will already exist, so this will actually be more efficient. It only won't exist
|
||||
# if a new file was added in a new subdirectory and this is the first time that file was ever parsed.
|
||||
if (!open(OUTPUTFILEHANDLE, '>' . $outputFile))
|
||||
{
|
||||
NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) );
|
||||
|
||||
open(OUTPUTFILEHANDLE, '>' . $outputFile)
|
||||
or die "Couldn't create output file " . $outputFile . "\n";
|
||||
};
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
my $usePrettify = (NaturalDocs::Settings->HighlightCode() || NaturalDocs::Settings->HighlightAnonymous());
|
||||
|
||||
|
||||
print OUTPUTFILEHANDLE
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>'
|
||||
. $self->BuildTitle($sourceFile)
|
||||
. '</title>'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($outputFile, $self->MainCSSFile(), 1) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->MainJavaScriptFile(), 1) . '">'
|
||||
. '</script>';
|
||||
|
||||
if ($usePrettify)
|
||||
{
|
||||
print OUTPUTFILEHANDLE
|
||||
'<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->PrettifyJavaScriptFile(), 1) . '">'
|
||||
. '</script>';
|
||||
}
|
||||
|
||||
print OUTPUTFILEHANDLE
|
||||
'<script language=JavaScript src="' . $self->MakeRelativeURL($outputFile, $self->SearchDataJavaScriptFile(), 1) . '">'
|
||||
. '</script>'
|
||||
|
||||
. '</head><body class="ContentPage" onLoad="NDOnLoad();' . ($usePrettify ? 'prettyPrint();' : '') . '">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->BuildContent($sourceFile, $parsedFile)
|
||||
. "\n\n\n"
|
||||
. $self->BuildFooter()
|
||||
. "\n\n\n"
|
||||
. $self->BuildMenu($sourceFile, undef)
|
||||
. "\n\n\n"
|
||||
. $self->BuildToolTips()
|
||||
. "\n\n\n"
|
||||
. '<div id=MSearchResultsWindow>'
|
||||
. '<iframe src="" frameborder=0 name=MSearchResults id=MSearchResults></iframe>'
|
||||
. '<a href="javascript:searchPanel.CloseResultsWindow()" id=MSearchResultsWindowClose>Close</a>'
|
||||
. '</div>'
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
. '</body></html>';
|
||||
|
||||
|
||||
close(OUTPUTFILEHANDLE);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: BuildIndex
|
||||
#
|
||||
# Builds an index for the passed type.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> to limit the index to, or undef if none.
|
||||
#
|
||||
sub BuildIndex #(type)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
my $indexTitle = $self->IndexTitleOf($type);
|
||||
|
||||
my $startIndexPage =
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<title>'
|
||||
. $indexTitle;
|
||||
|
||||
if (defined NaturalDocs::Menu->Title())
|
||||
{ $startIndexPage .= ' - ' . $self->StringToHTML(NaturalDocs::Menu->Title()); };
|
||||
|
||||
$startIndexPage .=
|
||||
'</title>'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($self->IndexDirectory(),
|
||||
$self->MainCSSFile()) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($self->IndexDirectory(),
|
||||
$self->MainJavaScriptFile()) . '"></script>'
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($self->IndexDirectory(),
|
||||
$self->SearchDataJavaScriptFile()) . '">'
|
||||
. '</script>'
|
||||
|
||||
. '</head><body class="IndexPage" onLoad="NDOnLoad()">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. "\n\n\n"
|
||||
|
||||
. '<div id=Index>'
|
||||
. '<div class=IPageTitle>'
|
||||
. $indexTitle
|
||||
. '</div>';
|
||||
|
||||
my $endIndexPage =
|
||||
'</div><!--Index-->'
|
||||
|
||||
. "\n\n\n"
|
||||
. $self->BuildFooter()
|
||||
. "\n\n\n"
|
||||
. $self->BuildMenu(undef, $type)
|
||||
. "\n\n\n"
|
||||
. '<div id=MSearchResultsWindow>'
|
||||
. '<iframe src="" frameborder=0 name=MSearchResults id=MSearchResults></iframe>'
|
||||
. '<a href="javascript:searchPanel.CloseResultsWindow()" id=MSearchResultsWindowClose>Close</a>'
|
||||
. '</div>'
|
||||
. "\n\n\n"
|
||||
|
||||
. $self->ClosingBrowserStyles()
|
||||
. '</body></html>';
|
||||
|
||||
|
||||
my $startSearchResultsPage =
|
||||
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" '
|
||||
. '"http://www.w3.org/TR/REC-html40/strict.dtd">' . "\n\n"
|
||||
|
||||
. '<html><head>'
|
||||
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
|
||||
|
||||
. '<link rel="stylesheet" type="text/css" href="' . $self->MakeRelativeURL($self->SearchResultsDirectory(),
|
||||
$self->MainCSSFile()) . '">'
|
||||
|
||||
. '<script language=JavaScript src="' . $self->MakeRelativeURL($self->SearchResultsDirectory(),
|
||||
$self->MainJavaScriptFile()) . '"></script>'
|
||||
|
||||
. '</head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()">'
|
||||
. $self->OpeningBrowserStyles()
|
||||
|
||||
. $self->StandardComments()
|
||||
|
||||
. "\n\n\n"
|
||||
|
||||
. '<div id=Index>';
|
||||
|
||||
|
||||
my $endSearchResultsPage =
|
||||
'</div>'
|
||||
. $self->ClosingBrowserStyles()
|
||||
. '</body></html>';
|
||||
|
||||
my $indexContent = NaturalDocs::SymbolTable->Index($type);
|
||||
my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage,
|
||||
$startSearchResultsPage, $endSearchResultsPage);
|
||||
$self->PurgeIndexFiles($type, $indexContent, $pageCount + 1);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateMenu
|
||||
#
|
||||
# Updates the menu in all the output files that weren't rebuilt. Also generates index.html.
|
||||
#
|
||||
sub UpdateMenu
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
|
||||
# Update the menu on unbuilt files.
|
||||
|
||||
my $filesToUpdate = NaturalDocs::Project->UnbuiltFilesWithContent();
|
||||
|
||||
foreach my $sourceFile (keys %$filesToUpdate)
|
||||
{
|
||||
$self->UpdateFile($sourceFile);
|
||||
};
|
||||
|
||||
|
||||
# Update the menu on unchanged index files.
|
||||
|
||||
my $indexes = NaturalDocs::Menu->Indexes();
|
||||
|
||||
foreach my $index (keys %$indexes)
|
||||
{
|
||||
if (!NaturalDocs::SymbolTable->IndexChanged($index))
|
||||
{
|
||||
$self->UpdateIndex($index);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# Update index.html
|
||||
|
||||
my $firstMenuEntry = $self->FindFirstFile();
|
||||
my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' );
|
||||
|
||||
# We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu.
|
||||
if (defined $firstMenuEntry)
|
||||
{
|
||||
open(INDEXFILEHANDLE, '>' . $indexFile)
|
||||
or die "Couldn't create output file " . $indexFile . ".\n";
|
||||
|
||||
binmode(INDEXFILEHANDLE, ':encoding(UTF-8)');
|
||||
|
||||
print INDEXFILEHANDLE
|
||||
'<html><head>'
|
||||
. '<meta http-equiv="Refresh" CONTENT="0; URL='
|
||||
. $self->MakeRelativeURL( NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html'),
|
||||
$self->OutputFileOf($firstMenuEntry->Target()), 1 ) . '">'
|
||||
. '</head></html>';
|
||||
|
||||
close INDEXFILEHANDLE;
|
||||
}
|
||||
|
||||
elsif (-e $indexFile)
|
||||
{
|
||||
unlink($indexFile);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateFile
|
||||
#
|
||||
# Updates an output file. Replaces the menu, HTML title, and footer. It opens the output file, makes the changes, and saves it
|
||||
# back to disk, which is much quicker than rebuilding the file from scratch if these were the only things that changed.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The source <FileName>.
|
||||
#
|
||||
# Dependencies:
|
||||
#
|
||||
# - Requires <Builder::BuildMenu()> to surround its content with the exact strings "<div id=Menu>" and "</div><!--Menu-->".
|
||||
# - Requires <Builder::BuildFooter()> to surround its content with the exact strings "<div id=Footer>" and
|
||||
# "</div><!--Footer-->".
|
||||
#
|
||||
sub UpdateFile #(sourceFile)
|
||||
{
|
||||
my ($self, $sourceFile) = @_;
|
||||
|
||||
my $outputFile = $self->OutputFileOf($sourceFile);
|
||||
|
||||
if (open(OUTPUTFILEHANDLE, '<' . $outputFile))
|
||||
{
|
||||
my $content;
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE);
|
||||
close(OUTPUTFILEHANDLE);
|
||||
|
||||
|
||||
$content =~ s{<title>[^<]*<\/title>}{'<title>' . $self->BuildTitle($sourceFile) . '</title>'}e;
|
||||
|
||||
$content =~ s/<div id=Menu>.*?<\/div><!--Menu-->/$self->BuildMenu($sourceFile, undef)/es;
|
||||
|
||||
$content =~ s/<div id=Footer>.*?<\/div><!--Footer-->/$self->BuildFooter()/e;
|
||||
|
||||
|
||||
open(OUTPUTFILEHANDLE, '>' . $outputFile);
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
print OUTPUTFILEHANDLE $content;
|
||||
close(OUTPUTFILEHANDLE);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: UpdateIndex
|
||||
#
|
||||
# Updates an index's output file. Replaces the menu and footer. It opens the output file, makes the changes, and saves it
|
||||
# back to disk, which is much quicker than rebuilding the file from scratch if these were the only things that changed.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The index <TopicType>, or undef if none.
|
||||
#
|
||||
sub UpdateIndex #(type)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
my $page = 1;
|
||||
|
||||
my $outputFile = $self->IndexFileOf($type, $page);
|
||||
|
||||
my $newMenu = $self->BuildMenu(undef, $type);
|
||||
my $newFooter = $self->BuildFooter();
|
||||
|
||||
while (-e $outputFile)
|
||||
{
|
||||
open(OUTPUTFILEHANDLE, '<' . $outputFile)
|
||||
or die "Couldn't open output file " . $outputFile . ".\n";
|
||||
|
||||
my $content;
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE);
|
||||
close(OUTPUTFILEHANDLE);
|
||||
|
||||
|
||||
$content =~ s/<div id=Menu>.*?<\/div><!--Menu-->/$newMenu/es;
|
||||
|
||||
$content =~ s/<div id=Footer>.*<\/div><!--Footer-->/$newFooter/e;
|
||||
|
||||
|
||||
open(OUTPUTFILEHANDLE, '>' . $outputFile)
|
||||
or die "Couldn't save output file " . $outputFile . ".\n";
|
||||
|
||||
binmode(OUTPUTFILEHANDLE, ':encoding(UTF-8)');
|
||||
print OUTPUTFILEHANDLE $content;
|
||||
close(OUTPUTFILEHANDLE);
|
||||
|
||||
$page++;
|
||||
$outputFile = $self->IndexFileOf($type, $page);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
3745
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTMLBase.pm
Executable file
3745
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Builder/HTMLBase.pm
Executable file
File diff suppressed because it is too large
Load Diff
869
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy.pm
Executable file
869
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy.pm
Executable file
@ -0,0 +1,869 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ClassHierarchy
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package that handles all the gory details of managing the class hierarchy. It handles the hierarchy itself, which files define
|
||||
# them, rebuilding the files that are affected by changes, and loading and saving them to a file.
|
||||
#
|
||||
# Usage and Dependencies:
|
||||
#
|
||||
# - <NaturalDocs::Settings> and <NaturalDocs::Project> must be initialized before use.
|
||||
#
|
||||
# - <NaturalDocs::SymbolTable> must be initialized before <Load()> is called. It must reflect the state as of the last time
|
||||
# Natural Docs was run.
|
||||
#
|
||||
# - <Load()> must be called to initialize the package. At this point, the <Information Functions> will return the state as
|
||||
# of the last time Natural Docs was run. You are free to resolve <NaturalDocs::SymbolTable()> afterwards.
|
||||
#
|
||||
# - <Purge()> must be called, and then <NaturalDocs::Parser->ParseForInformation()> must be called on all files that
|
||||
# have changed so it can fully resolve the hierarchy via the <Modification Functions()>. Afterwards the
|
||||
# <Information Functions> will reflect the current state of the code.
|
||||
#
|
||||
# - <Save()> must be called to commit any changes to the symbol table back to disk.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use NaturalDocs::ClassHierarchy::Class;
|
||||
use NaturalDocs::ClassHierarchy::File;
|
||||
|
||||
package NaturalDocs::ClassHierarchy;
|
||||
|
||||
use Encode qw(encode_utf8 decode_utf8);
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
#
|
||||
# handle: CLASS_HIERARCHY_FILEHANDLE
|
||||
# The file handle used with <ClassHierarchy.nd>.
|
||||
#
|
||||
|
||||
#
|
||||
# hash: classes
|
||||
#
|
||||
# A hash of all the classes. The keys are the class <SymbolStrings> and the values are <NaturalDocs::ClassHierarchy::Classes>.
|
||||
#
|
||||
my %classes;
|
||||
|
||||
#
|
||||
# hash: files
|
||||
#
|
||||
# A hash of the hierarchy information referenced by file. The keys are the <FileNames>, and the values are
|
||||
# <NaturalDocs::ClassHierarchy::File>s.
|
||||
#
|
||||
my %files;
|
||||
|
||||
#
|
||||
# hash: parentReferences
|
||||
#
|
||||
# A hash of all the parent reference strings and what they resolve to. The keys are the <ReferenceStrings> and the values are
|
||||
# the class <SymbolStrings> that they resolve to.
|
||||
#
|
||||
my %parentReferences;
|
||||
|
||||
#
|
||||
# object: watchedFile
|
||||
#
|
||||
# A <NaturalDocs::ClassHierarchy::File> object of the file being watched for changes. This is compared to the version in <files>
|
||||
# to see if anything was changed since the last parse.
|
||||
#
|
||||
my $watchedFile;
|
||||
|
||||
#
|
||||
# string: watchedFileName
|
||||
#
|
||||
# The <FileName> of the watched file, if any. If there is no watched file, this will be undef.
|
||||
#
|
||||
my $watchedFileName;
|
||||
|
||||
#
|
||||
# bool: dontRebuildFiles
|
||||
#
|
||||
# A bool to set if you don't want changes in the hierarchy to cause files to be rebuilt.
|
||||
#
|
||||
my $dontRebuildFiles;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Files
|
||||
|
||||
|
||||
#
|
||||
# File: ClassHierarchy.nd
|
||||
#
|
||||
# Stores the class hierarchy on disk.
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# > [BINARY_FORMAT]
|
||||
# > [VersionInt: app version]
|
||||
#
|
||||
# The standard <BINARY_FORMAT> and <VersionInt> header.
|
||||
#
|
||||
# > [SymbolString: class or undef to end]
|
||||
#
|
||||
# Next we begin a class segment with its <SymbolString>. These continue until the end of the file. Only defined classes are
|
||||
# included.
|
||||
#
|
||||
# > [UInt32: number of files]
|
||||
# > [UString16: file] [UString16: file] ...
|
||||
#
|
||||
# Next there is the number of files that define that class. It's a UInt32, which seems like overkill, but I could imagine every
|
||||
# file in a huge C++ project being under the same namespace, and thus contributing its own definition. It's theoretically
|
||||
# possible.
|
||||
#
|
||||
# Following the number is that many file names. You must remember the index of each file, as they will be important later.
|
||||
# Indexes start at one because zero has a special meaning.
|
||||
#
|
||||
# > [UInt8: number of parents]
|
||||
# > ( [ReferenceString (no type): parent]
|
||||
# > [UInt32: file index] [UInt32: file index] ... [UInt32: 0] ) ...
|
||||
#
|
||||
# Next there is the number of parents defined for this class. For each one, we define a parent segment, which consists of
|
||||
# its <ReferenceString>, and then a zero-terminated string of indexes of the files that define that parent as part of that class.
|
||||
# The indexes start at one, and are into the list of files we saw previously.
|
||||
#
|
||||
# Note that we do store class segments for classes without parents, but not for undefined classes.
|
||||
#
|
||||
# This concludes a class segment. These segments continue until an undef <SymbolString>.
|
||||
#
|
||||
# See Also:
|
||||
#
|
||||
# <File Format Conventions>
|
||||
#
|
||||
# Revisions:
|
||||
#
|
||||
# 1.52:
|
||||
#
|
||||
# - Changed AString16s to UString16s.
|
||||
#
|
||||
# 1.22:
|
||||
#
|
||||
# - Classes and parents switched from AString16s to <SymbolStrings> and <ReferenceStrings>.
|
||||
# - A ending undef <SymbolString> was added to the end. Previously it stopped when the file ran out.
|
||||
#
|
||||
# 1.2:
|
||||
#
|
||||
# - This file was introduced in 1.2.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: File Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Load
|
||||
#
|
||||
# Loads the class hierarchy from disk.
|
||||
#
|
||||
sub Load
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
$dontRebuildFiles = 1;
|
||||
|
||||
my $fileIsOkay;
|
||||
my $fileName = NaturalDocs::Project->DataFile('ClassHierarchy.nd');
|
||||
|
||||
if (!NaturalDocs::Settings->RebuildData() && open(CLASS_HIERARCHY_FILEHANDLE, '<' . $fileName))
|
||||
{
|
||||
# See if it's binary.
|
||||
binmode(CLASS_HIERARCHY_FILEHANDLE);
|
||||
|
||||
my $firstChar;
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $firstChar, 1);
|
||||
|
||||
if ($firstChar != ::BINARY_FORMAT())
|
||||
{
|
||||
close(CLASS_HIERARCHY_FILEHANDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
my $version = NaturalDocs::Version->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE);
|
||||
|
||||
# Last file format change was 1.52
|
||||
|
||||
if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.52') ))
|
||||
{ $fileIsOkay = 1; }
|
||||
else
|
||||
{ close(CLASS_HIERARCHY_FILEHANDLE); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
if (!$fileIsOkay)
|
||||
{
|
||||
NaturalDocs::Project->ReparseEverything();
|
||||
}
|
||||
else
|
||||
{
|
||||
my $raw;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
# [SymbolString: class or undef to end]
|
||||
|
||||
my $class = NaturalDocs::SymbolString->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE);
|
||||
|
||||
if (!defined $class)
|
||||
{ last; };
|
||||
|
||||
# [UInt32: number of files]
|
||||
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $raw, 4);
|
||||
my $numberOfFiles = unpack('N', $raw);
|
||||
|
||||
my @files;
|
||||
|
||||
while ($numberOfFiles)
|
||||
{
|
||||
# [UString16: file]
|
||||
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $raw, 2);
|
||||
my $fileLength = unpack('n', $raw);
|
||||
|
||||
my $file;
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $file, $fileLength);
|
||||
$file = decode_utf8($file);
|
||||
|
||||
push @files, $file;
|
||||
$self->AddClass($file, $class, NaturalDocs::Languages->LanguageOf($file)->Name());
|
||||
|
||||
$numberOfFiles--;
|
||||
};
|
||||
|
||||
# [UInt8: number of parents]
|
||||
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $raw, 1);
|
||||
my $numberOfParents = unpack('C', $raw);
|
||||
|
||||
while ($numberOfParents)
|
||||
{
|
||||
# [ReferenceString (no type): parent]
|
||||
|
||||
my $parent = NaturalDocs::ReferenceString->FromBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE,
|
||||
::BINARYREF_NOTYPE(),
|
||||
::REFERENCE_CH_PARENT());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
# [UInt32: file index or 0]
|
||||
|
||||
read(CLASS_HIERARCHY_FILEHANDLE, $raw, 4);
|
||||
my $fileIndex = unpack('N', $raw);
|
||||
|
||||
if ($fileIndex == 0)
|
||||
{ last; }
|
||||
|
||||
$self->AddParentReference( $files[$fileIndex - 1], $class, $parent );
|
||||
};
|
||||
|
||||
$numberOfParents--;
|
||||
};
|
||||
};
|
||||
|
||||
close(CLASS_HIERARCHY_FILEHANDLE);
|
||||
};
|
||||
|
||||
$dontRebuildFiles = undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Save
|
||||
#
|
||||
# Saves the class hierarchy to disk.
|
||||
#
|
||||
sub Save
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
open (CLASS_HIERARCHY_FILEHANDLE, '>' . NaturalDocs::Project->DataFile('ClassHierarchy.nd'))
|
||||
or die "Couldn't save " . NaturalDocs::Project->DataFile('ClassHierarchy.nd') . ".\n";
|
||||
|
||||
binmode(CLASS_HIERARCHY_FILEHANDLE);
|
||||
|
||||
print CLASS_HIERARCHY_FILEHANDLE '' . ::BINARY_FORMAT();
|
||||
NaturalDocs::Version->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, NaturalDocs::Settings->AppVersion());
|
||||
|
||||
while (my ($class, $classObject) = each %classes)
|
||||
{
|
||||
if ($classObject->IsDefined())
|
||||
{
|
||||
# [SymbolString: class or undef to end]
|
||||
|
||||
NaturalDocs::SymbolString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, $class);
|
||||
|
||||
# [UInt32: number of files]
|
||||
|
||||
my @definitions = $classObject->Definitions();
|
||||
my %definitionIndexes;
|
||||
|
||||
print CLASS_HIERARCHY_FILEHANDLE pack('N', scalar @definitions);
|
||||
|
||||
for (my $i = 0; $i < scalar @definitions; $i++)
|
||||
{
|
||||
# [UString16: file]
|
||||
my $uDefinition = encode_utf8($definitions[$i]);
|
||||
print CLASS_HIERARCHY_FILEHANDLE pack('na*', length($uDefinition), $uDefinition);
|
||||
$definitionIndexes{$definitions[$i]} = $i + 1;
|
||||
};
|
||||
|
||||
# [UInt8: number of parents]
|
||||
|
||||
my @parents = $classObject->ParentReferences();
|
||||
print CLASS_HIERARCHY_FILEHANDLE pack('C', scalar @parents);
|
||||
|
||||
foreach my $parent (@parents)
|
||||
{
|
||||
# [ReferenceString (no type): parent]
|
||||
|
||||
NaturalDocs::ReferenceString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, $parent, ::BINARYREF_NOTYPE());
|
||||
|
||||
# [UInt32: file index]
|
||||
|
||||
my @parentDefinitions = $classObject->ParentReferenceDefinitions($parent);
|
||||
|
||||
foreach my $parentDefinition (@parentDefinitions)
|
||||
{
|
||||
print CLASS_HIERARCHY_FILEHANDLE pack('N', $definitionIndexes{$parentDefinition});
|
||||
};
|
||||
|
||||
# [UInt32: 0]
|
||||
print CLASS_HIERARCHY_FILEHANDLE pack('N', 0);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# [SymbolString: class or undef to end]
|
||||
|
||||
NaturalDocs::SymbolString->ToBinaryFile(\*CLASS_HIERARCHY_FILEHANDLE, undef);
|
||||
|
||||
close(CLASS_HIERARCHY_FILEHANDLE);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Purge
|
||||
#
|
||||
# Purges the hierarchy of files that no longer have Natural Docs content.
|
||||
#
|
||||
sub Purge
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $filesToPurge = NaturalDocs::Project->FilesToPurge();
|
||||
|
||||
foreach my $file (keys %$filesToPurge)
|
||||
{
|
||||
$self->DeleteFile($file);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Interface Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: OnInterpretationChange
|
||||
#
|
||||
# Called by <NaturalDocs::SymbolTable> whenever a class hierarchy reference's intepretation changes, meaning it switched
|
||||
# from one symbol to another.
|
||||
#
|
||||
# reference - The <ReferenceString> whose current interpretation changed.
|
||||
#
|
||||
sub OnInterpretationChange #(reference)
|
||||
{
|
||||
my ($self, $reference) = @_;
|
||||
|
||||
if (NaturalDocs::ReferenceString->TypeOf($reference) == ::REFERENCE_CH_PARENT())
|
||||
{
|
||||
# The approach here is simply to completely delete the reference and readd it. This is less than optimal efficiency, since it's
|
||||
# being removed and added from %files too, even though that isn't required. However, the simpler code is worth it
|
||||
# considering this will only happen when a parent reference becomes defined or undefined, or on the rare languages (like C#)
|
||||
# that allow relative parent references.
|
||||
|
||||
my $oldTargetSymbol = $parentReferences{$reference};
|
||||
my $oldTargetObject = $classes{$oldTargetSymbol};
|
||||
|
||||
my @classesWithReferenceParent = $oldTargetObject->Children();
|
||||
|
||||
# Each entry is an arrayref of file names. Indexes are the same as classesWithReferenceParent's.
|
||||
my @filesDefiningReferenceParent;
|
||||
|
||||
foreach my $classWithReferenceParent (@classesWithReferenceParent)
|
||||
{
|
||||
my $fileList = [ $classes{$classWithReferenceParent}->ParentReferenceDefinitions($reference) ];
|
||||
push @filesDefiningReferenceParent, $fileList;
|
||||
|
||||
foreach my $fileDefiningReferenceParent (@$fileList)
|
||||
{
|
||||
$self->DeleteParentReference($fileDefiningReferenceParent, $classWithReferenceParent, $reference);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# This will force the reference to be reinterpreted on the next add.
|
||||
|
||||
delete $parentReferences{$reference};
|
||||
|
||||
|
||||
# Now we can just readd it.
|
||||
|
||||
for (my $i = 0; $i < scalar @classesWithReferenceParent; $i++)
|
||||
{
|
||||
foreach my $file (@{$filesDefiningReferenceParent[$i]})
|
||||
{
|
||||
$self->AddParentReference($file, $classesWithReferenceParent[$i], $reference);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# The only way for a REFERENCE_CH_CLASS reference to change is if the symbol is deleted. That will be handled by
|
||||
# <AnalyzeChanges()>, so we don't need to do anything here.
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnTargetSymbolChange
|
||||
#
|
||||
# Called by <NaturalDocs::SymbolTable> whenever a class hierarchy reference's target symbol changes, but the reference
|
||||
# still resolves to the same symbol.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# reference - The <ReferenceString> that was affected by the change.
|
||||
#
|
||||
sub OnTargetSymbolChange #(reference)
|
||||
{
|
||||
my ($self, $reference) = @_;
|
||||
|
||||
my $type = NaturalDocs::ReferenceString->TypeOf($reference);
|
||||
my $class;
|
||||
|
||||
if ($type == ::REFERENCE_CH_PARENT())
|
||||
{ $class = $parentReferences{$reference}; }
|
||||
else # ($type == ::REFERENCE_CH_CLASS())
|
||||
{
|
||||
# Class references are global absolute, so we can just yank the symbol.
|
||||
(undef, $class, undef, undef, undef, undef) = NaturalDocs::ReferenceString->InformationOf($reference);
|
||||
};
|
||||
|
||||
$self->RebuildFilesFor($class, 1, 0, 1);
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: AddClass
|
||||
#
|
||||
# Adds a class to the hierarchy.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> the class was defined in.
|
||||
# class - The class <SymbolString>.
|
||||
# languageName - The name of the language this applies to.
|
||||
#
|
||||
# Note:
|
||||
#
|
||||
# The file parameter must be defined when using this function externally. It may be undef for internal use only.
|
||||
#
|
||||
sub AddClass #(file, class, languageName)
|
||||
{
|
||||
my ($self, $file, $class, $languageName) = @_;
|
||||
|
||||
if (!exists $classes{$class})
|
||||
{
|
||||
$classes{$class} = NaturalDocs::ClassHierarchy::Class->New();
|
||||
NaturalDocs::SymbolTable->AddReference($self->ClassReferenceOf($class, $languageName), $file)
|
||||
};
|
||||
|
||||
if (defined $file)
|
||||
{
|
||||
# If this was the first definition for this class...
|
||||
if ($classes{$class}->AddDefinition($file))
|
||||
{ $self->RebuildFilesFor($class, 1, 1, 1); };
|
||||
|
||||
if (!exists $files{$file})
|
||||
{ $files{$file} = NaturalDocs::ClassHierarchy::File->New(); };
|
||||
|
||||
$files{$file}->AddClass($class);
|
||||
|
||||
if (defined $watchedFileName)
|
||||
{ $watchedFile->AddClass($class); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddParentReference
|
||||
#
|
||||
# Adds a class-parent relationship to the hierarchy. The classes will be created if they don't already exist.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> the reference was defined in.
|
||||
# class - The class <SymbolString>.
|
||||
# symbol - The parent class <SymbolString>.
|
||||
# scope - The package <SymbolString> that the reference appeared in.
|
||||
# using - An arrayref of package <SymbolStrings> that the reference has access to via "using" statements.
|
||||
# resolvingFlags - Any <Resolving Flags> to be used when resolving the reference.
|
||||
#
|
||||
# Alternate Parameters:
|
||||
#
|
||||
# file - The <FileName> the reference was defined in.
|
||||
# class - The class <SymbolString>.
|
||||
# reference - The parent <ReferenceString>.
|
||||
#
|
||||
sub AddParentReference #(file, class, symbol, scope, using, resolvingFlags) or (file, class, reference)
|
||||
{
|
||||
my ($self, $file, $class, $symbol, $parentReference);
|
||||
|
||||
if (scalar @_ == 7)
|
||||
{
|
||||
my ($scope, $using, $resolvingFlags);
|
||||
($self, $file, $class, $symbol, $scope, $using, $resolvingFlags) = @_;
|
||||
|
||||
$parentReference = NaturalDocs::ReferenceString->MakeFrom(::REFERENCE_CH_PARENT(), $symbol,
|
||||
NaturalDocs::Languages->LanguageOf($file)->Name(),
|
||||
$scope, $using, $resolvingFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
($self, $file, $class, $parentReference) = @_;
|
||||
$symbol = (NaturalDocs::ReferenceString->InformationOf($parentReference))[1];
|
||||
};
|
||||
|
||||
|
||||
# In case it doesn't already exist.
|
||||
$self->AddClass($file, $class);
|
||||
|
||||
my $parent;
|
||||
if (exists $parentReferences{$parentReference})
|
||||
{
|
||||
$parent = $parentReferences{$parentReference};
|
||||
}
|
||||
else
|
||||
{
|
||||
NaturalDocs::SymbolTable->AddReference($parentReference, $file);
|
||||
my $parentTarget = NaturalDocs::SymbolTable->References($parentReference);
|
||||
|
||||
if (defined $parentTarget)
|
||||
{ $parent = $parentTarget->Symbol(); }
|
||||
else
|
||||
{ $parent = $symbol; };
|
||||
|
||||
# In case it doesn't already exist.
|
||||
$self->AddClass(undef, $parent);
|
||||
|
||||
$parentReferences{$parentReference} = $parent;
|
||||
};
|
||||
|
||||
|
||||
# If this defined a new parent...
|
||||
if ($classes{$class}->AddParentReference($parentReference, $file, \%parentReferences))
|
||||
{
|
||||
$classes{$parent}->AddChild($class);
|
||||
|
||||
$self->RebuildFilesFor($class, 0, 1, 0);
|
||||
$self->RebuildFilesFor($parent, 0, 1, 0);
|
||||
};
|
||||
|
||||
$files{$file}->AddParentReference($class, $parentReference);
|
||||
|
||||
if (defined $watchedFileName)
|
||||
{ $watchedFile->AddParentReference($class, $parentReference); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: WatchFileForChanges
|
||||
#
|
||||
# Watches a file for changes, which can then be applied by <AnalyzeChanges()>. Definitions are not deleted via a DeleteClass()
|
||||
# function. Instead, a file is watched for changes, reparsed, and then a comparison is made to look for definitions that
|
||||
# disappeared and any other relevant changes.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> to watch.
|
||||
#
|
||||
sub WatchFileForChanges #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
$watchedFile = NaturalDocs::ClassHierarchy::File->New();
|
||||
$watchedFileName = $file;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AnalyzeChanges
|
||||
#
|
||||
# Checks the watched file for any changes that occured since the last time is was parsed, and updates the hierarchy as
|
||||
# necessary. Also sends any files that are affected to <NaturalDocs::Project->RebuildFile()>.
|
||||
#
|
||||
sub AnalyzeChanges
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
# If the file didn't have any classes before, and it still doesn't, it wont be in %files.
|
||||
if (exists $files{$watchedFileName})
|
||||
{
|
||||
my @originalClasses = $files{$watchedFileName}->Classes();
|
||||
|
||||
foreach my $originalClass (@originalClasses)
|
||||
{
|
||||
# If the class isn't there the second time around...
|
||||
if (!$watchedFile->HasClass($originalClass))
|
||||
{ $self->DeleteClass($watchedFileName, $originalClass); }
|
||||
|
||||
else
|
||||
{
|
||||
my @originalParents = $files{$watchedFileName}->ParentReferencesOf($originalClass);
|
||||
|
||||
foreach my $originalParent (@originalParents)
|
||||
{
|
||||
# If the parent reference wasn't there the second time around...
|
||||
if (!$watchedFile->HasParentReference($originalClass, $originalParent))
|
||||
{ $self->DeleteParentReference($watchedFileName, $originalClass, $originalParent); };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
$watchedFile = undef;
|
||||
$watchedFileName = undef;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: ParentsOf
|
||||
# Returns a <SymbolString> array of the passed class' parents, or an empty array if none. Note that not all of them may be
|
||||
# defined.
|
||||
#
|
||||
sub ParentsOf #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
|
||||
if (exists $classes{$class})
|
||||
{ return $classes{$class}->Parents(); }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: ChildrenOf
|
||||
# Returns a <SymbolString> array of the passed class' children, or an empty array if none. Note that not all of them may be
|
||||
# defined.
|
||||
#
|
||||
sub ChildrenOf #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
|
||||
if (exists $classes{$class})
|
||||
{ return $classes{$class}->Children(); }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteFile
|
||||
#
|
||||
# Deletes a file and everything defined in it.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName>.
|
||||
#
|
||||
sub DeleteFile #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (!exists $files{$file})
|
||||
{ return; };
|
||||
|
||||
my @classes = $files{$file}->Classes();
|
||||
foreach my $class (@classes)
|
||||
{
|
||||
$self->DeleteClass($file, $class);
|
||||
};
|
||||
|
||||
delete $files{$file};
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteClass
|
||||
#
|
||||
# Deletes a class definition from a file. Will also delete any parent references from this class and file. Will rebuild any file
|
||||
# affected unless <dontRebuildFiles> is set.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> that defines the class.
|
||||
# class - The class <SymbolString>.
|
||||
#
|
||||
sub DeleteClass #(file, class)
|
||||
{
|
||||
my ($self, $file, $class) = @_;
|
||||
|
||||
my @parents = $files{$file}->ParentReferencesOf($class);
|
||||
foreach my $parent (@parents)
|
||||
{
|
||||
$self->DeleteParentReference($file, $class, $parent);
|
||||
};
|
||||
|
||||
$files{$file}->DeleteClass($class);
|
||||
|
||||
# If we're deleting the last definition of this class.
|
||||
if ($classes{$class}->DeleteDefinition($file))
|
||||
{
|
||||
if (!$classes{$class}->HasChildren())
|
||||
{
|
||||
delete $classes{$class};
|
||||
|
||||
if (!$dontRebuildFiles)
|
||||
{ NaturalDocs::Project->RebuildFile($file); };
|
||||
}
|
||||
else
|
||||
{ $self->RebuildFilesFor($class, 0, 1, 1); };
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteParentReference
|
||||
#
|
||||
# Deletes a class' parent reference and returns whether it resulted in the loss of a parent class. Will rebuild any file affected
|
||||
# unless <dontRebuildFiles> is set.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> that defines the reference.
|
||||
# class - The class <SymbolString>.
|
||||
# reference - The parent <ReferenceString>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the class lost a parent as a result of this, it will return its <SymbolString>. It will return undef otherwise.
|
||||
#
|
||||
sub DeleteParentReference #(file, class, reference)
|
||||
{
|
||||
my ($self, $file, $class, $reference) = @_;
|
||||
|
||||
if (!exists $classes{$class})
|
||||
{ return; };
|
||||
|
||||
$files{$file}->DeleteParentReference($class, $reference);
|
||||
|
||||
my $deletedParent = $classes{$class}->DeleteParentReference($reference, $file, \%parentReferences);
|
||||
|
||||
if (defined $deletedParent)
|
||||
{
|
||||
my $deletedParentObject = $classes{$deletedParent};
|
||||
|
||||
$deletedParentObject->DeleteChild($class);
|
||||
|
||||
$self->RebuildFilesFor($deletedParent, 0, 1, 0);
|
||||
$self->RebuildFilesFor($class, 0, 1, 0);
|
||||
|
||||
if (!$deletedParentObject->HasChildren() && !$deletedParentObject->IsDefined())
|
||||
{
|
||||
delete $classes{$deletedParent};
|
||||
NaturalDocs::SymbolTable->DeleteReference(
|
||||
$self->ClassReferenceOf($class, NaturalDocs::Languages->LanguageOf($file)->Name()) );
|
||||
};
|
||||
|
||||
return $deletedParent;
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ClassReferenceOf
|
||||
#
|
||||
# Returns the <REFERENCE_CH_CLASS> <ReferenceString> of the passed class <SymbolString>.
|
||||
#
|
||||
sub ClassReferenceOf #(class, languageName)
|
||||
{
|
||||
my ($self, $class, $languageName) = @_;
|
||||
|
||||
return NaturalDocs::ReferenceString->MakeFrom(::REFERENCE_CH_CLASS(), $class, $languageName, undef, undef,
|
||||
::RESOLVE_ABSOLUTE() | ::RESOLVE_NOPLURAL());
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: RebuildFilesFor
|
||||
#
|
||||
# Calls <NaturalDocs::Project->RebuildFile()> for every file defining the passed class, its parents, and/or its children.
|
||||
# Returns without doing anything if <dontRebuildFiles> is set.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# class - The class <SymbolString>.
|
||||
# rebuildParents - Whether to rebuild the class' parents.
|
||||
# rebuildSelf - Whether to rebuild the class.
|
||||
# rebuildChildren - Whether to rebuild the class' children.
|
||||
#
|
||||
sub RebuildFilesFor #(class, rebuildParents, rebuildSelf, rebuildChildren)
|
||||
{
|
||||
my ($self, $class, $rebuildParents, $rebuildSelf, $rebuildChildren) = @_;
|
||||
|
||||
if ($dontRebuildFiles)
|
||||
{ return; };
|
||||
|
||||
my @classesToBuild;
|
||||
|
||||
if ($rebuildParents)
|
||||
{ @classesToBuild = $classes{$class}->Parents(); };
|
||||
if ($rebuildSelf)
|
||||
{ push @classesToBuild, $class; };
|
||||
if ($rebuildChildren)
|
||||
{ push @classesToBuild, $classes{$class}->Children(); };
|
||||
|
||||
foreach my $classToBuild (@classesToBuild)
|
||||
{
|
||||
my @definitions = $classes{$classToBuild}->Definitions();
|
||||
|
||||
foreach my $definition (@definitions)
|
||||
{ NaturalDocs::Project->RebuildFile($definition); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
413
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/Class.pm
Executable file
413
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/Class.pm
Executable file
@ -0,0 +1,413 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::ClassHierarchy::Class
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# An object that stores information about a class in the hierarchy. It does not store its <SymbolString>; it assumes that it will
|
||||
# be stored in a hashref where the key is the <SymbolString>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::ClassHierarchy::Class;
|
||||
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The keys are the constants below.
|
||||
#
|
||||
# DEFINITIONS - An existence hashref of all the <FileNames> which define this class. Undef if none.
|
||||
# PARENTS - An existence hashref of the <SymbolStrings> of all the parents this class has.
|
||||
# CHILDREN - An existence hashref of the <SymbolStrings> of all the children this class has.
|
||||
# PARENT_REFERENCES - A hashref of the parent <ReferenceStrings> this class has. The keys are the <ReferenceStrings>,
|
||||
# and the values are existence hashrefs of all the <FileNames> that define them. Undef if none.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'DEFINITIONS', 'PARENTS', 'CHILDREN', 'PARENT_REFERENCES';
|
||||
# Dependency: New() depends on the order of these constants, as well as the class not being derived from any other.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new class.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
# Dependency: This function depends on the order of the constants, as well as the class not being derived from any other.
|
||||
my ($package, $definitionFile) = @_;
|
||||
|
||||
my $object = [ undef, undef, undef, undef ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a rew definition of this class and returns if that was the first definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> the definition appears in.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether this was the first definition of this class.
|
||||
#
|
||||
sub AddDefinition #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
my $wasFirst;
|
||||
|
||||
if (!defined $self->[DEFINITIONS])
|
||||
{
|
||||
$self->[DEFINITIONS] = { };
|
||||
$wasFirst = 1;
|
||||
};
|
||||
|
||||
$self->[DEFINITIONS]->{$file} = 1;
|
||||
|
||||
return $wasFirst;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes the definition of this class and returns if there are no more definitions. Note that if there are no more
|
||||
# definitions, you may still want to keep the object around if <HasChildren()> returns true.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> the definition appears in.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether this deleted the last definition of this class.
|
||||
#
|
||||
sub DeleteDefinition #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{
|
||||
delete $self->[DEFINITIONS]->{$file};
|
||||
|
||||
if (!scalar keys %{$self->[DEFINITIONS]})
|
||||
{
|
||||
$self->[DEFINITIONS] = undef;
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddParentReference
|
||||
#
|
||||
# Adds a parent reference to the class and return whether it resulted in a new parent class.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# reference - The <ReferenceString> used to determine the parent.
|
||||
# file - The <FileName> the parent reference is in.
|
||||
# referenceTranslations - A hashref of what each reference currently resolves to. The keys are the
|
||||
# <ReferenceStrings> and the values are class <SymbolStrings>. It should include an entry for
|
||||
# the reference parameter above.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the reference adds a new parent, it will return that parent's <SymbolString>. Otherwise it will return undef.
|
||||
#
|
||||
sub AddParentReference #(reference, file, referenceTranslations)
|
||||
{
|
||||
my ($self, $reference, $file, $referenceTranslations) = @_;
|
||||
|
||||
if (!defined $self->[PARENT_REFERENCES])
|
||||
{ $self->[PARENT_REFERENCES] = { }; };
|
||||
if (!defined $self->[PARENTS])
|
||||
{ $self->[PARENTS] = { }; };
|
||||
|
||||
|
||||
if (!exists $self->[PARENT_REFERENCES]->{$reference})
|
||||
{
|
||||
$self->[PARENT_REFERENCES]->{$reference} = { $file => 1 };
|
||||
|
||||
my $symbol = $referenceTranslations->{$reference};
|
||||
|
||||
if (!exists $self->[PARENTS]->{$symbol})
|
||||
{
|
||||
$self->[PARENTS]->{$symbol} = 1;
|
||||
return $symbol;
|
||||
}
|
||||
else
|
||||
{ return undef; };
|
||||
}
|
||||
else
|
||||
{
|
||||
$self->[PARENT_REFERENCES]->{$reference}->{$file} = 1;
|
||||
return undef;
|
||||
};
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteParentReference
|
||||
#
|
||||
# Deletes a parent reference from the class and return whether it resulted in a loss of a parent class.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# reference - The <ReferenceString> used to determine the parent.
|
||||
# file - The <FileName> the parent declaration is in.
|
||||
# referenceTranslations - A hashref of what each reference currently resolves to. The keys are the
|
||||
# <ReferenceStrings> and the values are class <SymbolStrings>. It should include an entry for
|
||||
# the reference parameter above.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If this causes a parent class to be lost, it will return that parent's <SymbolString>. Otherwise it will return undef.
|
||||
#
|
||||
sub DeleteParentReference #(reference, file, referenceTranslations)
|
||||
{
|
||||
my ($self, $reference, $file, $referenceTranslations) = @_;
|
||||
|
||||
if (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference} &&
|
||||
exists $self->[PARENT_REFERENCES]->{$reference}->{$file})
|
||||
{
|
||||
delete $self->[PARENT_REFERENCES]->{$reference}->{$file};
|
||||
|
||||
# Quit if there are other definitions of this reference.
|
||||
if (scalar keys %{$self->[PARENT_REFERENCES]->{$reference}})
|
||||
{ return undef; };
|
||||
|
||||
delete $self->[PARENT_REFERENCES]->{$reference};
|
||||
|
||||
if (!scalar keys %{$self->[PARENT_REFERENCES]})
|
||||
{ $self->[PARENT_REFERENCES] = undef; };
|
||||
|
||||
my $parent = $referenceTranslations->{$reference};
|
||||
|
||||
# Check if any other references resolve to the same parent.
|
||||
if (defined $self->[PARENT_REFERENCES])
|
||||
{
|
||||
foreach my $parentReference (keys %{$self->[PARENT_REFERENCES]})
|
||||
{
|
||||
if ($referenceTranslations->{$parentReference} eq $parent)
|
||||
{ return undef; };
|
||||
};
|
||||
};
|
||||
|
||||
# If we got this far, no other parent references resolve to this symbol.
|
||||
|
||||
delete $self->[PARENTS]->{$parent};
|
||||
|
||||
if (!scalar keys %{$self->[PARENTS]})
|
||||
{ $self->[PARENTS] = undef; };
|
||||
|
||||
return $parent;
|
||||
}
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddChild
|
||||
# Adds a child <SymbolString> to the class. Unlike <AddParentReference()>, this does not keep track of anything other than
|
||||
# whether it has it or not.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# child - The <SymbolString> to add.
|
||||
#
|
||||
sub AddChild #(child)
|
||||
{
|
||||
my ($self, $child) = @_;
|
||||
|
||||
if (!defined $self->[CHILDREN])
|
||||
{ $self->[CHILDREN] = { }; };
|
||||
|
||||
$self->[CHILDREN]->{$child} = 1;
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteChild
|
||||
# Deletes a child <SymbolString> from the class. Unlike <DeleteParentReference()>, this does not keep track of anything other
|
||||
# than whether it has it or not.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# child - The <SymbolString> to delete.
|
||||
#
|
||||
sub DeleteChild #(child)
|
||||
{
|
||||
my ($self, $child) = @_;
|
||||
|
||||
if (defined $self->[CHILDREN])
|
||||
{
|
||||
delete $self->[CHILDREN]->{$child};
|
||||
|
||||
if (!scalar keys %{$self->[CHILDREN]})
|
||||
{ $self->[CHILDREN] = undef; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
#
|
||||
# Function: Definitions
|
||||
# Returns an array of the <FileNames> that define this class, or an empty array if none.
|
||||
#
|
||||
sub Definitions
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{ return keys %{$self->[DEFINITIONS]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: IsDefinedIn
|
||||
# Returns whether the class is defined in the passed <FileName>.
|
||||
#
|
||||
sub IsDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{ return exists $self->[DEFINITIONS]->{$file}; }
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: IsDefined
|
||||
# Returns whether the class is defined in any files.
|
||||
#
|
||||
sub IsDefined
|
||||
{
|
||||
my ($self) = @_;
|
||||
return defined $self->[DEFINITIONS];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: ParentReferences
|
||||
# Returns an array of the parent <ReferenceStrings>, or an empty array if none.
|
||||
#
|
||||
sub ParentReferences
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if (defined $self->[PARENT_REFERENCES])
|
||||
{ return keys %{$self->[PARENT_REFERENCES]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasParentReference
|
||||
# Returns whether the class has the passed parent <ReferenceString>.
|
||||
#
|
||||
sub HasParentReference #(reference)
|
||||
{
|
||||
my ($self, $reference) = @_;
|
||||
return (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference});
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasParentReferences
|
||||
# Returns whether the class has any parent <ReferenceStrings>.
|
||||
#
|
||||
sub HasParentReferences
|
||||
{
|
||||
my ($self) = @_;
|
||||
return defined $self->[PARENT_REFERENCES];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: Parents
|
||||
# Returns an array of the parent <SymbolStrings>, or an empty array if none.
|
||||
#
|
||||
sub Parents
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if (defined $self->[PARENTS])
|
||||
{ return keys %{$self->[PARENTS]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasParents
|
||||
# Returns whether the class has any parent <SymbolStrings> defined.
|
||||
#
|
||||
sub HasParents
|
||||
{
|
||||
my ($self) = @_;
|
||||
return defined $self->[PARENTS];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: Children
|
||||
# Returns an array of the child <SymbolStrings>, or an empty array if none.
|
||||
#
|
||||
sub Children
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if (defined $self->[CHILDREN])
|
||||
{ return keys %{$self->[CHILDREN]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasChildren
|
||||
# Returns whether any child <SymbolStrings> are defined.
|
||||
#
|
||||
sub HasChildren
|
||||
{
|
||||
my ($self) = @_;
|
||||
return defined $self->[CHILDREN];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParentReferenceDefinitions
|
||||
# Returns an array of the <FileNames> which define the passed parent <ReferenceString>, or an empty array if none.
|
||||
#
|
||||
sub ParentReferenceDefinitions #(reference)
|
||||
{
|
||||
my ($self, $reference) = @_;
|
||||
|
||||
if (defined $self->[PARENT_REFERENCES] && exists $self->[PARENT_REFERENCES]->{$reference})
|
||||
{ return keys %{$self->[PARENT_REFERENCES]->{$reference}}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
|
||||
1;
|
158
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/File.pm
Executable file
158
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ClassHierarchy/File.pm
Executable file
@ -0,0 +1,158 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::ClassHierarchy::File
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# An object that stores information about what hierarchy information is present in a file. It does not store its <FileName>; it
|
||||
# assumes that it will be stored in a hashref where the key is the <FileName>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::ClassHierarchy::File;
|
||||
|
||||
|
||||
#
|
||||
# Topic: Implementation
|
||||
#
|
||||
# Since there's only one member in the class, and it's a hashref, the class is simply the hashref itself blessed as a class.
|
||||
# The keys are the class <SymbolStrings> that are defined in the file, and the values are existence hashrefs of each class'
|
||||
# parent <ReferenceStrings>, or undef if none.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new class.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my ($package) = @_;
|
||||
|
||||
my $object = { };
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
#
|
||||
# Function: AddClass
|
||||
# Adds a rew class <SymbolString> to the file.
|
||||
#
|
||||
sub AddClass #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
|
||||
if (!exists $self->{$class})
|
||||
{ $self->{$class} = undef; };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteClass
|
||||
# Deletes a class <SymbolString> from the file.
|
||||
#
|
||||
sub DeleteClass #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
delete $self->{$class};
|
||||
};
|
||||
|
||||
#
|
||||
# Function: AddParentReference
|
||||
# Adds a parent <ReferenceString> to a class <SymbolString>.
|
||||
#
|
||||
sub AddParentReference #(class, parentReference)
|
||||
{
|
||||
my ($self, $class, $parent) = @_;
|
||||
|
||||
if (!exists $self->{$class} || !defined $self->{$class})
|
||||
{ $self->{$class} = { }; };
|
||||
|
||||
$self->{$class}->{$parent} = 1;
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteParentReference
|
||||
# Deletes a parent <ReferenceString> from a class <SymbolString>.
|
||||
#
|
||||
sub DeleteParentReference #(class, parent)
|
||||
{
|
||||
my ($self, $class, $parent) = @_;
|
||||
|
||||
if (exists $self->{$class})
|
||||
{
|
||||
delete $self->{$class}->{$parent};
|
||||
|
||||
if (!scalar keys %{$self->{$class}})
|
||||
{ $self->{$class} = undef; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Classes
|
||||
# Returns an array of the class <SymbolStrings> that are defined by this file, or an empty array if none.
|
||||
#
|
||||
sub Classes
|
||||
{
|
||||
my ($self) = @_;
|
||||
return keys %{$self};
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasClass
|
||||
# Returns whether the file defines the passed class <SymbolString>.
|
||||
#
|
||||
sub HasClass #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
return exists $self->{$class};
|
||||
};
|
||||
|
||||
#
|
||||
# Function: ParentReferencesOf
|
||||
# Returns an array of the parent <ReferenceStrings> that are defined by the class, or an empty array if none.
|
||||
#
|
||||
sub ParentReferencesOf #(class)
|
||||
{
|
||||
my ($self, $class) = @_;
|
||||
|
||||
if (!exists $self->{$class} || !defined $self->{$class})
|
||||
{ return ( ); }
|
||||
else
|
||||
{ return keys %{$self->{$class}}; };
|
||||
};
|
||||
|
||||
#
|
||||
# Function: HasParentReference
|
||||
# Returns whether the file defines the passed class <SymbolString> and parent <ReferenceString>.
|
||||
#
|
||||
sub HasParentReference #(class, parent)
|
||||
{
|
||||
my ($self, $class, $parent) = @_;
|
||||
|
||||
if (!$self->HasClass($class))
|
||||
{ return undef; };
|
||||
|
||||
return exists $self->{$class}->{$parent};
|
||||
};
|
||||
|
||||
|
||||
1;
|
508
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ConfigFile.pm
Executable file
508
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ConfigFile.pm
Executable file
@ -0,0 +1,508 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ConfigFile
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to manage Natural Docs' configuration files.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# - Only one configuration file can be managed with this package at a time. You must close the file before opening another
|
||||
# one.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::ConfigFile;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Topic: Format
|
||||
#
|
||||
# All configuration files are text files.
|
||||
#
|
||||
# > # [comment]
|
||||
#
|
||||
# Comments start with the # character.
|
||||
#
|
||||
# > Format: [version]
|
||||
#
|
||||
# All configuration files *must* have a format line as its first line containing content. Whitespace and comments are permitted
|
||||
# ahead of it.
|
||||
#
|
||||
# > [keyword]: [value]
|
||||
#
|
||||
# Keywords can only contain <CFChars>. Keywords are not case sensitive. Values can be anything and run until the end of
|
||||
# the line or a comment.
|
||||
#
|
||||
# > [value]
|
||||
#
|
||||
# Lines that don't start with a valid keyword format are considered to be all value.
|
||||
#
|
||||
# > [line] { [line] } [line]
|
||||
#
|
||||
# Files supporting brace groups (specified in <Open()>) may also have braces that can appear anywhere. It allows more than
|
||||
# one thing to appear per line, which isn't supported otherwise. Consequently, values may not have braces.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Type: CFChars
|
||||
#
|
||||
# The characters that can appear in configuration file keywords and user-defined element names: letters, numbers, spaces,
|
||||
# dashes, slashes, apostrophes, and periods.
|
||||
#
|
||||
# Although the list above is exhaustive, it should be noted that you especially can *not* use colons (messes up keyword: value
|
||||
# sequences) commas (messes up item, item, item list sequences) and hashes (messes up comment detection.)
|
||||
#
|
||||
# You can search the source code for [CFChars] to find all the instances where this definition is used.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
#
|
||||
# handle: CONFIG_FILEHANDLE
|
||||
#
|
||||
# The file handle used for the configuration file.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# string: file
|
||||
#
|
||||
# The <FileName> for the current configuration file being parsed.
|
||||
#
|
||||
my $file;
|
||||
|
||||
|
||||
#
|
||||
# var: lineReader
|
||||
#
|
||||
# The <LineReader> used to read the configuration file.
|
||||
#
|
||||
my $lineReader;
|
||||
|
||||
|
||||
#
|
||||
# array: errors
|
||||
#
|
||||
# An array of errors added by <AddError()>. Every odd entry is the line number, and every even entry following is the
|
||||
# error message.
|
||||
#
|
||||
my @errors;
|
||||
|
||||
|
||||
#
|
||||
# var: lineNumber
|
||||
#
|
||||
# The current line number for the configuration file.
|
||||
#
|
||||
my $lineNumber;
|
||||
|
||||
|
||||
#
|
||||
# bool: hasBraceGroups
|
||||
#
|
||||
# Whether the file has brace groups or not.
|
||||
#
|
||||
my $hasBraceGroups;
|
||||
|
||||
|
||||
#
|
||||
# array: virtualLines
|
||||
#
|
||||
# An array of virtual lines if a line from the file contained more than one.
|
||||
#
|
||||
# Files with brace groups may have more than one virtual line per actual file line, such as "Group: A { Group: B". When that
|
||||
# happens, any extra virtual lines are put into here so they can be returned on the next call.
|
||||
#
|
||||
my @virtualLines;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Open
|
||||
#
|
||||
# Opens a configuration file for parsing and returns the format <VersionInt>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> to parse.
|
||||
# hasBraceGroups - Whether the file supports brace groups or not. If so, lines with braces will be split apart behind the
|
||||
# scenes.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The <VersionInt> of the file, or undef if the file doesn't exist.
|
||||
#
|
||||
sub Open #(file, hasBraceGroups)
|
||||
{
|
||||
my $self;
|
||||
($self, $file, $hasBraceGroups) = @_;
|
||||
|
||||
@errors = ( );
|
||||
|
||||
# It will be incremented to one when the first line is read from the file.
|
||||
$lineNumber = 0;
|
||||
|
||||
open(CONFIG_FILEHANDLE, '<' . $file) or return undef;
|
||||
$lineReader = NaturalDocs::LineReader->New(\*CONFIG_FILEHANDLE);
|
||||
|
||||
|
||||
# Get the format line.
|
||||
|
||||
my ($keyword, $value, $comment) = $self->GetLine();
|
||||
|
||||
if ($keyword eq 'format')
|
||||
{ return NaturalDocs::Version->FromString($value); }
|
||||
else
|
||||
{ die "The first content line in " . $file . " must be the Format: line.\n"; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Close
|
||||
#
|
||||
# Closes the current configuration file.
|
||||
#
|
||||
sub Close
|
||||
{
|
||||
my $self = shift;
|
||||
close(CONFIG_FILEHANDLE);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetLine
|
||||
#
|
||||
# Returns the next line containing content, or an empty array if none.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Returns the array ( keyword, value, comment ), or an empty array if none. All tabs will be converted to spaces, and all
|
||||
# whitespace will be condensed into a single space.
|
||||
#
|
||||
# keyword - The keyword part of the line, if any. Is converted to lowercase and doesn't include the colon. If the file supports
|
||||
# brace groups, opening and closing braces will be returned as keywords.
|
||||
# value - The value part of the line, minus any whitespace. Keeps its original case.
|
||||
# comment - The comment following the line, if any. This includes the # symbol and a leading space if there was
|
||||
# any whitespace, since it may be significant. Otherwise undef. Used for lines where the # character needs to be
|
||||
# accepted as part of the value.
|
||||
#
|
||||
sub GetLine
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my ($line, $comment);
|
||||
|
||||
|
||||
# Get the next line with content.
|
||||
|
||||
do
|
||||
{
|
||||
# Get the next line.
|
||||
|
||||
my $isFileLine;
|
||||
|
||||
if (scalar @virtualLines)
|
||||
{
|
||||
$line = shift @virtualLines;
|
||||
$isFileLine = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$line = $lineReader->Get();
|
||||
$lineNumber++;
|
||||
|
||||
if (!defined $line)
|
||||
{ return ( ); };
|
||||
|
||||
# Condense spaces and tabs into a single space.
|
||||
$line =~ tr/\t / /s;
|
||||
$isFileLine = 1;
|
||||
};
|
||||
|
||||
|
||||
# Split off the comment.
|
||||
|
||||
if ($line =~ /^(.*?)( ?#.*)$/)
|
||||
{ ($line, $comment) = ($1, $2); }
|
||||
else
|
||||
{ $comment = undef; };
|
||||
|
||||
|
||||
# Split any brace groups.
|
||||
|
||||
if ($isFileLine && $hasBraceGroups && $line =~ /[\{\}]/)
|
||||
{
|
||||
($line, @virtualLines) = split(/([\{\}])/, $line);
|
||||
|
||||
$virtualLines[-1] .= $comment;
|
||||
$comment = undef;
|
||||
};
|
||||
|
||||
|
||||
# Remove whitespace.
|
||||
|
||||
$line =~ s/^ //;
|
||||
$line =~ s/ $//;
|
||||
$comment =~ s/ $//;
|
||||
# We want to keep the leading space on a comment.
|
||||
}
|
||||
while (!$line);
|
||||
|
||||
|
||||
# Process the line.
|
||||
|
||||
if ($hasBraceGroups && ($line eq '{' || $line eq '}'))
|
||||
{
|
||||
return ($line, undef, undef);
|
||||
};
|
||||
|
||||
|
||||
if ($line =~ /^([a-z0-9\ \'\/\.\-]+?) ?: ?(.*)$/i) # [CFChars]
|
||||
{
|
||||
my ($keyword, $value) = ($1, $2);
|
||||
return (lc($keyword), $value, $comment);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return (undef, $line, $comment);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: LineNumber
|
||||
#
|
||||
# Returns the line number for the line last returned by <GetLine()>.
|
||||
#
|
||||
sub LineNumber
|
||||
{ return $lineNumber; };
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Error Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: AddError
|
||||
#
|
||||
# Stores an error for the current configuration file. Will be attached to the last line read by <GetLine()>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# message - The error message.
|
||||
# lineNumber - The line number to use. If not specified, it will use the line number from the last call to <GetLine()>.
|
||||
#
|
||||
sub AddError #(message, lineNumber)
|
||||
{
|
||||
my ($self, $message, $messageLineNumber) = @_;
|
||||
|
||||
if (!defined $messageLineNumber)
|
||||
{ $messageLineNumber = $lineNumber; };
|
||||
|
||||
push @errors, $messageLineNumber, $message;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ErrorCount
|
||||
#
|
||||
# Returns how many errors the configuration file has.
|
||||
#
|
||||
sub ErrorCount
|
||||
{
|
||||
return (scalar @errors) / 2;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PrintErrorsAndAnnotateFile
|
||||
#
|
||||
# Prints the errors to STDERR in the standard GNU format and annotates the configuration file with them. It does *not* end
|
||||
# execution. <Close()> *must* be called before this function.
|
||||
#
|
||||
sub PrintErrorsAndAnnotateFile
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if (scalar @errors)
|
||||
{
|
||||
open(CONFIG_FILEHANDLE, '<' . $file);
|
||||
|
||||
my $lineReader = NaturalDocs::LineReader->New(\*CONFIG_FILEHANDLE);
|
||||
my @lines = $lineReader->GetAll();
|
||||
|
||||
close(CONFIG_FILEHANDLE);
|
||||
|
||||
# We need to keep track of both the real and the original line numbers. The original line numbers are for matching errors in
|
||||
# the errors array, and don't include any comment lines added or deleted. Line number is the current line number including
|
||||
# those comment lines for sending to the display.
|
||||
my $lineNumber = 1;
|
||||
my $originalLineNumber = 1;
|
||||
|
||||
open(CONFIG_FILEHANDLE, '>' . $file);
|
||||
|
||||
# We don't want to keep the old error header, if present.
|
||||
if ($lines[0] =~ /^\# There (?:is an error|are \d+ errors) in this file\./)
|
||||
{
|
||||
shift @lines;
|
||||
$originalLineNumber++;
|
||||
|
||||
# We want to drop the blank line after it as well.
|
||||
if ($lines[0] eq "\n")
|
||||
{
|
||||
shift @lines;
|
||||
$originalLineNumber++;
|
||||
};
|
||||
};
|
||||
|
||||
if ($self->ErrorCount() == 1)
|
||||
{
|
||||
print CONFIG_FILEHANDLE
|
||||
"# There is an error in this file. Search for ERROR to find it.\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print CONFIG_FILEHANDLE
|
||||
"# There are " . $self->ErrorCount() . " errors in this file. Search for ERROR to find them.\n\n";
|
||||
};
|
||||
|
||||
$lineNumber += 2;
|
||||
|
||||
|
||||
foreach my $line (@lines)
|
||||
{
|
||||
while (scalar @errors && $originalLineNumber == $errors[0])
|
||||
{
|
||||
my $errorLine = shift @errors;
|
||||
my $errorMessage = shift @errors;
|
||||
|
||||
print CONFIG_FILEHANDLE "# ERROR: " . $errorMessage . "\n";
|
||||
|
||||
# Use the GNU error format, which should make it easier to handle errors when Natural Docs is part of a build process.
|
||||
# See http://www.gnu.org/prep/standards_15.html
|
||||
|
||||
$errorMessage = lcfirst($errorMessage);
|
||||
$errorMessage =~ s/\.$//;
|
||||
|
||||
print STDERR 'NaturalDocs:' . $file . ':' . $lineNumber . ': ' . $errorMessage . "\n";
|
||||
|
||||
$lineNumber++;
|
||||
};
|
||||
|
||||
# We want to remove error lines from previous runs.
|
||||
if (substr($line, 0, 9) ne '# ERROR: ')
|
||||
{
|
||||
print CONFIG_FILEHANDLE $line;
|
||||
$lineNumber++;
|
||||
};
|
||||
|
||||
$originalLineNumber++;
|
||||
};
|
||||
|
||||
# Clean up any remaining errors.
|
||||
while (scalar @errors)
|
||||
{
|
||||
my $errorLine = shift @errors;
|
||||
my $errorMessage = shift @errors;
|
||||
|
||||
print CONFIG_FILEHANDLE "# ERROR: " . $errorMessage . "\n";
|
||||
|
||||
# Use the GNU error format, which should make it easier to handle errors when Natural Docs is part of a build process.
|
||||
# See http://www.gnu.org/prep/standards_15.html
|
||||
|
||||
$errorMessage = lcfirst($errorMessage);
|
||||
$errorMessage =~ s/\.$//;
|
||||
|
||||
print STDERR 'NaturalDocs:' . $file . ':' . $lineNumber . ': ' . $errorMessage . "\n";
|
||||
};
|
||||
|
||||
close(CONFIG_FILEHANDLE);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Misc Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: HasOnlyCFChars
|
||||
#
|
||||
# Returns whether the passed string contains only <CFChars>.
|
||||
#
|
||||
sub HasOnlyCFChars #(string)
|
||||
{
|
||||
my ($self, $string) = @_;
|
||||
return ($string =~ /^[a-z0-9\ \.\-\/\']*$/i); # [CFChars]
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CFCharNames
|
||||
#
|
||||
# Returns a plain-english list of <CFChars> which can be embedded in a sentence. For example, "You can only use
|
||||
# [CFCharsList()] in the name.
|
||||
#
|
||||
sub CFCharNames
|
||||
{
|
||||
# [CFChars]
|
||||
return 'letters, numbers, spaces, periods, dashes, slashes, and apostrophes';
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Obscure
|
||||
#
|
||||
# Obscures the passed text so that it is not user editable and returns it. The encoding method is not secure; it is just designed
|
||||
# to be fast and to discourage user editing.
|
||||
#
|
||||
sub Obscure #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
# ` is specifically chosen to encode to space because of its rarity. We don't want a trailing one to get cut off before decoding.
|
||||
$text =~ tr{a-zA-Z0-9\ \\\/\.\:\_\-\`}
|
||||
{pY9fGc\`R8lAoE\\uIdH6tN\/7sQjKx0B5mW\.vZ41PyFg\:CrLaO\_eUi2DhT\-nSqJkXb3MwVz\ };
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Unobscure
|
||||
#
|
||||
# Restores text encoded with <Obscure()> and returns it.
|
||||
#
|
||||
sub Unobscure #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$text =~ tr{pY9fGc\`R8lAoE\\uIdH6tN\/7sQjKx0B5mW\.vZ41PyFg\:CrLaO\_eUi2DhT\-nSqJkXb3MwVz\ }
|
||||
{a-zA-Z0-9\ \\\/\.\:\_\-\`};
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
|
||||
|
||||
1;
|
166
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Constants.pm
Executable file
166
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Constants.pm
Executable file
@ -0,0 +1,166 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Constants
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Constants that are used throughout the script. All are exported by default.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Constants;
|
||||
|
||||
use vars qw(@EXPORT @ISA);
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT = ('MENU_TITLE', 'MENU_SUBTITLE', 'MENU_FILE', 'MENU_GROUP', 'MENU_TEXT', 'MENU_LINK', 'MENU_FOOTER',
|
||||
'MENU_INDEX', 'MENU_FORMAT', 'MENU_ENDOFORIGINAL', 'MENU_DATA',
|
||||
|
||||
'MENU_FILE_NOAUTOTITLE', 'MENU_GROUP_UPDATETITLES', 'MENU_GROUP_UPDATESTRUCTURE',
|
||||
'MENU_GROUP_UPDATEORDER', 'MENU_GROUP_HASENDOFORIGINAL',
|
||||
'MENU_GROUP_UNSORTED', 'MENU_GROUP_FILESSORTED',
|
||||
'MENU_GROUP_FILESANDGROUPSSORTED', 'MENU_GROUP_EVERYTHINGSORTED',
|
||||
'MENU_GROUP_ISINDEXGROUP',
|
||||
|
||||
'FILE_NEW', 'FILE_CHANGED', 'FILE_SAME', 'FILE_DOESNTEXIST');
|
||||
|
||||
#
|
||||
# Topic: Assumptions
|
||||
#
|
||||
# - No constant here will ever be zero.
|
||||
# - All constants are exported by default.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Virtual Types
|
||||
# These are only groups of constants, but should be treated like typedefs or enums. Each one represents a distinct type and
|
||||
# their values should only be one of their constants or undef.
|
||||
|
||||
|
||||
#
|
||||
# Constants: MenuEntryType
|
||||
#
|
||||
# The types of entries that can appear in the menu.
|
||||
#
|
||||
# MENU_TITLE - The title of the menu.
|
||||
# MENU_SUBTITLE - The sub-title of the menu.
|
||||
# MENU_FILE - A source file, relative to the source directory.
|
||||
# MENU_GROUP - A group.
|
||||
# MENU_TEXT - Arbitrary text.
|
||||
# MENU_LINK - A web link.
|
||||
# MENU_FOOTER - Footer text.
|
||||
# MENU_INDEX - An index.
|
||||
# MENU_FORMAT - The version of Natural Docs the menu file was generated with.
|
||||
# MENU_ENDOFORIGINAL - A dummy entry that marks where the original group content ends. This is used when automatically
|
||||
# changing the groups so that the alphabetization or lack thereof can be detected without being
|
||||
# affected by new entries tacked on to the end.
|
||||
# MENU_DATA - Data not meant for user editing.
|
||||
#
|
||||
# Dependency:
|
||||
#
|
||||
# <PreviousMenuState.nd> depends on these values all being able to fit into a UInt8, i.e. <= 255.
|
||||
#
|
||||
use constant MENU_TITLE => 1;
|
||||
use constant MENU_SUBTITLE => 2;
|
||||
use constant MENU_FILE => 3;
|
||||
use constant MENU_GROUP => 4;
|
||||
use constant MENU_TEXT => 5;
|
||||
use constant MENU_LINK => 6;
|
||||
use constant MENU_FOOTER => 7;
|
||||
use constant MENU_INDEX => 8;
|
||||
use constant MENU_FORMAT => 9;
|
||||
use constant MENU_ENDOFORIGINAL => 10;
|
||||
use constant MENU_DATA => 11;
|
||||
|
||||
|
||||
#
|
||||
# Constants: FileStatus
|
||||
#
|
||||
# What happened to a file since Natural Docs' last execution.
|
||||
#
|
||||
# FILE_NEW - The file has been added since the last run.
|
||||
# FILE_CHANGED - The file has been modified since the last run.
|
||||
# FILE_SAME - The file hasn't been modified since the last run.
|
||||
# FILE_DOESNTEXIST - The file doesn't exist, or was deleted.
|
||||
#
|
||||
use constant FILE_NEW => 1;
|
||||
use constant FILE_CHANGED => 2;
|
||||
use constant FILE_SAME => 3;
|
||||
use constant FILE_DOESNTEXIST => 4;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Flags
|
||||
# These constants can be combined with each other.
|
||||
|
||||
|
||||
#
|
||||
# Constants: Menu Entry Flags
|
||||
#
|
||||
# The various flags that can apply to a menu entry. You cannot mix flags of different types, since they may overlap.
|
||||
#
|
||||
# File Flags:
|
||||
#
|
||||
# MENU_FILE_NOAUTOTITLE - Whether the file is auto-titled or not.
|
||||
#
|
||||
# Group Flags:
|
||||
#
|
||||
# MENU_GROUP_UPDATETITLES - The group should have its auto-titles regenerated.
|
||||
# MENU_GROUP_UPDATESTRUCTURE - The group should be checked for structural changes, such as being removed or being
|
||||
# split into subgroups.
|
||||
# MENU_GROUP_UPDATEORDER - The group should be resorted.
|
||||
#
|
||||
# MENU_GROUP_HASENDOFORIGINAL - Whether the group contains a dummy <MENU_ENDOFORIGINAL> entry.
|
||||
# MENU_GROUP_ISINDEXGROUP - Whether the group is used primarily for <MENU_INDEX> entries. <MENU_TEXT> entries
|
||||
# are tolerated.
|
||||
#
|
||||
# MENU_GROUP_UNSORTED - The group's contents are not sorted.
|
||||
# MENU_GROUP_FILESSORTED - The group's files are sorted alphabetically.
|
||||
# MENU_GROUP_FILESANDGROUPSSORTED - The group's files and sub-groups are sorted alphabetically.
|
||||
# MENU_GROUP_EVERYTHINGSORTED - All entries in the group are sorted alphabetically.
|
||||
#
|
||||
use constant MENU_FILE_NOAUTOTITLE => 0x0001;
|
||||
|
||||
use constant MENU_GROUP_UPDATETITLES => 0x0001;
|
||||
use constant MENU_GROUP_UPDATESTRUCTURE => 0x0002;
|
||||
use constant MENU_GROUP_UPDATEORDER => 0x0004;
|
||||
use constant MENU_GROUP_HASENDOFORIGINAL => 0x0008;
|
||||
|
||||
# This could really be a two-bit field instead of four flags, but it's not worth the effort since it's only used internally.
|
||||
use constant MENU_GROUP_UNSORTED => 0x0010;
|
||||
use constant MENU_GROUP_FILESSORTED => 0x0020;
|
||||
use constant MENU_GROUP_FILESANDGROUPSSORTED => 0x0040;
|
||||
use constant MENU_GROUP_EVERYTHINGSORTED => 0x0080;
|
||||
|
||||
use constant MENU_GROUP_ISINDEXGROUP => 0x0100;
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: IsClassHierarchyReference
|
||||
# Returns whether the passed <ReferenceType> belongs to <NaturalDocs::ClassHierarchy>.
|
||||
#
|
||||
sub IsClassHierarchyReference #(reference)
|
||||
{
|
||||
my ($self, $reference) = @_;
|
||||
return ($reference == ::REFERENCE_CH_CLASS() || $reference == ::REFERENCE_CH_PARENT());
|
||||
};
|
||||
|
||||
|
||||
|
||||
1;
|
101
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/DefineMembers.pm
Executable file
101
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/DefineMembers.pm
Executable file
@ -0,0 +1,101 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::DefineMembers
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A custom Perl pragma to define member constants and accessors for use in Natural Docs objects while supporting inheritance.
|
||||
#
|
||||
# Each member will be defined as a numeric constant which should be used as that variable's index into the object arrayref.
|
||||
# They will be assigned sequentially from zero, and take into account any members defined this way in parent classes. Note
|
||||
# that you can *not* use multiple inheritance with this method.
|
||||
#
|
||||
# If a parameter ends in parenthesis, it will be generated as an accessor for the previous member. If it also starts with "Set",
|
||||
# the accessor will accept a single parameter to replace the value with. If it's followed with "duparrayref", it will assume the
|
||||
# parameter is either an arrayref or undef, and if the former, will duplicate it to set the value.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# > package MyPackage;
|
||||
# >
|
||||
# > use NaturalDocs::DefineMembers 'VAR_A', 'VarA()', 'SetVarA()',
|
||||
# > 'VAR_B', 'VarB()',
|
||||
# > 'VAR_C',
|
||||
# > 'VAR_D', 'VarD()', 'SetVarD() duparrayref';
|
||||
# >
|
||||
# > sub SetC #(C)
|
||||
# > {
|
||||
# > my ($self, $c) = @_;
|
||||
# > $self->[VAR_C] = $c;
|
||||
# > };
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
package NaturalDocs::DefineMembers;
|
||||
|
||||
sub import #(member, member, ...)
|
||||
{
|
||||
my ($self, @parameters) = @_;
|
||||
my $package = caller();
|
||||
|
||||
no strict 'refs';
|
||||
my $parent = ${$package . '::ISA'}[0];
|
||||
use strict 'refs';
|
||||
|
||||
my $memberConstant = 0;
|
||||
my $lastMemberName;
|
||||
|
||||
if (defined $parent && $parent->can('END_OF_MEMBERS'))
|
||||
{ $memberConstant = $parent->END_OF_MEMBERS(); };
|
||||
|
||||
my $code = '{ package ' . $package . ";\n";
|
||||
|
||||
foreach my $parameter (@parameters)
|
||||
{
|
||||
if ($parameter =~ /^(.+)\(\) *(duparrayref)?$/i)
|
||||
{
|
||||
my ($functionName, $pragma) = ($1, lc($2));
|
||||
|
||||
if ($functionName =~ /^Set/)
|
||||
{
|
||||
if ($pragma eq 'duparrayref')
|
||||
{
|
||||
$code .=
|
||||
'sub ' . $functionName . '
|
||||
{
|
||||
if (defined $_[1])
|
||||
{ $_[0]->[' . $lastMemberName . '] = [ @{$_[1]} ]; }
|
||||
else
|
||||
{ $_[0]->[' . $lastMemberName . '] = undef; };
|
||||
};' . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$code .= 'sub ' . $functionName . ' { $_[0]->[' . $lastMemberName . '] = $_[1]; };' . "\n";
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
$code .= 'sub ' . $functionName . ' { return $_[0]->[' . $lastMemberName . ']; };' . "\n";
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
$code .= 'use constant ' . $parameter . ' => ' . $memberConstant . ";\n";
|
||||
$memberConstant++;
|
||||
$lastMemberName = $parameter;
|
||||
};
|
||||
};
|
||||
|
||||
$code .= 'use constant END_OF_MEMBERS => ' . $memberConstant . ";\n";
|
||||
$code .= '};';
|
||||
|
||||
eval $code;
|
||||
};
|
||||
|
||||
1;
|
306
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Error.pm
Executable file
306
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Error.pm
Executable file
@ -0,0 +1,306 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Error
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# Manages all aspects of error handling in Natural Docs.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
$SIG{'__DIE__'} = \&NaturalDocs::Error::CatchDeath;
|
||||
|
||||
|
||||
package NaturalDocs::Error;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
|
||||
#
|
||||
# handle: FH_CRASHREPORT
|
||||
# The filehandle used for generating crash reports.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# var: stackTrace
|
||||
# The stack trace generated by <CatchDeath()>.
|
||||
#
|
||||
my $stackTrace;
|
||||
|
||||
|
||||
#
|
||||
# var: softDeath
|
||||
# Whether the program exited using <SoftDeath()>.
|
||||
#
|
||||
my $softDeath;
|
||||
|
||||
|
||||
#
|
||||
# var: currentAction
|
||||
# What Natural Docs was doing when it crashed. This stores strings generated by functions like <OnStartParsing()>.
|
||||
#
|
||||
my $currentAction;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: SoftDeath
|
||||
#
|
||||
# Generates a "soft" death, which means the program exits like with Perl's die(), but no crash report will be generated.
|
||||
#
|
||||
# Parameter:
|
||||
#
|
||||
# message - The error message to die with.
|
||||
#
|
||||
sub SoftDeath #(message)
|
||||
{
|
||||
my ($self, $message) = @_;
|
||||
|
||||
$softDeath = 1;
|
||||
if ($message !~ /\n$/)
|
||||
{ $message .= "\n"; };
|
||||
|
||||
die $message;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnStartParsing
|
||||
#
|
||||
# Called whenever <NaturalDocs::Parser> starts parsing a source file.
|
||||
#
|
||||
sub OnStartParsing #(FileName file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
$currentAction = 'Parsing ' . $file;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnEndParsing
|
||||
#
|
||||
# Called whenever <NaturalDocs::Parser> is done parsing a source file.
|
||||
#
|
||||
sub OnEndParsing #(FileName file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
$currentAction = undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnStartBuilding
|
||||
#
|
||||
# Called whenever <NaturalDocs::Builder> starts building a source file.
|
||||
#
|
||||
sub OnStartBuilding #(FileName file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
$currentAction = 'Building ' . $file;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnEndBuilding
|
||||
#
|
||||
# Called whenever <NaturalDocs::Builder> is done building a source file.
|
||||
#
|
||||
sub OnEndBuilding #(FileName file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
$currentAction = undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HandleDeath
|
||||
#
|
||||
# Should be called whenever Natural Docs dies out of execution.
|
||||
#
|
||||
sub HandleDeath
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $reason = $::EVAL_ERROR;
|
||||
$reason =~ s/[\n\r]+$//;
|
||||
|
||||
my $errorMessage =
|
||||
"\n"
|
||||
. "Natural Docs encountered the following error and was stopped:\n"
|
||||
. "\n"
|
||||
. " " . $reason . "\n"
|
||||
. "\n"
|
||||
|
||||
. "You can get help at the following web site:\n"
|
||||
. "\n"
|
||||
. " " . NaturalDocs::Settings->AppURL() . "\n"
|
||||
. "\n";
|
||||
|
||||
if (!$softDeath)
|
||||
{
|
||||
my $crashReport = $self->GenerateCrashReport();
|
||||
|
||||
if ($crashReport)
|
||||
{
|
||||
$errorMessage .=
|
||||
"If sending an error report, please include the information found in the\n"
|
||||
. "following file:\n"
|
||||
. "\n"
|
||||
. " " . $crashReport . "\n"
|
||||
. "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$errorMessage .=
|
||||
"If sending an error report, please include the following information:\n"
|
||||
. "\n"
|
||||
. " Natural Docs version: " . NaturalDocs::Settings->TextAppVersion() . "\n"
|
||||
. " Perl version: " . $self->PerlVersion() . " on " . $::OSNAME . "\n"
|
||||
. "\n";
|
||||
};
|
||||
};
|
||||
|
||||
die $errorMessage;
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: PerlVersion
|
||||
# Returns the current Perl version as a string.
|
||||
#
|
||||
sub PerlVersion
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $perlVersion;
|
||||
|
||||
if ($^V)
|
||||
{ $perlVersion = sprintf('%vd', $^V); }
|
||||
if (!$perlVersion || substr($perlVersion, 0, 1) eq '%')
|
||||
{ $perlVersion = $]; };
|
||||
|
||||
return $perlVersion;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GenerateCrashReport
|
||||
#
|
||||
# Generates a report and returns the <FileName> it's located at. Returns undef if it could not generate one.
|
||||
#
|
||||
sub GenerateCrashReport
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $errorMessage = $::EVAL_ERROR;
|
||||
$errorMessage =~ s/[\r\n]+$//;
|
||||
|
||||
my $reportDirectory = NaturalDocs::Settings->ProjectDirectory();
|
||||
|
||||
if (!$reportDirectory || !-d $reportDirectory)
|
||||
{ return undef; };
|
||||
|
||||
my $file = NaturalDocs::File->JoinPaths($reportDirectory, 'LastCrash.txt');
|
||||
|
||||
open(FH_CRASHREPORT, '>' . $file) or return undef;
|
||||
|
||||
print FH_CRASHREPORT
|
||||
'Crash Message:' . "\n\n"
|
||||
. ' ' . $errorMessage . "\n\n";
|
||||
|
||||
if ($currentAction)
|
||||
{
|
||||
print FH_CRASHREPORT
|
||||
'Current Action:' . "\n\n"
|
||||
. ' ' . $currentAction . "\n\n";
|
||||
};
|
||||
|
||||
print FH_CRASHREPORT
|
||||
'Natural Docs version ' . NaturalDocs::Settings->TextAppVersion() . "\n"
|
||||
. 'Perl version ' . $self->PerlVersion . ' on ' . $::OSNAME . "\n\n"
|
||||
. 'Command Line:' . "\n\n"
|
||||
. ' ' . join(' ', @ARGV) . "\n\n";
|
||||
|
||||
if ($stackTrace)
|
||||
{
|
||||
print FH_CRASHREPORT
|
||||
'Stack Trace:' . "\n\n"
|
||||
. $stackTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
print FH_CRASHREPORT
|
||||
'Stack Trace not available.' . "\n\n";
|
||||
};
|
||||
|
||||
close(FH_CRASHREPORT);
|
||||
return $file;
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Signal Handlers
|
||||
|
||||
|
||||
#
|
||||
# Function: CatchDeath
|
||||
#
|
||||
# Catches Perl die calls.
|
||||
#
|
||||
# *IMPORTANT:* This function is a signal handler and should not be called manually. Also, because of this, it does not have
|
||||
# a $self parameter.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# message - The error message to die with.
|
||||
#
|
||||
sub CatchDeath #(message)
|
||||
{
|
||||
# No $self because it's a signal handler.
|
||||
my $message = shift;
|
||||
|
||||
if (!$NaturalDocs::Error::softDeath)
|
||||
{
|
||||
my $i = 0;
|
||||
my ($lastPackage, $lastFile, $lastLine, $lastFunction);
|
||||
|
||||
while (my ($package, $file, $line, $function) = caller($i))
|
||||
{
|
||||
if ($i != 0)
|
||||
{ $stackTrace .= ', called from' . "\n"; };
|
||||
|
||||
$stackTrace .= ' ' . $function;
|
||||
|
||||
if (defined $lastLine)
|
||||
{
|
||||
$stackTrace .= ', line ' . $lastLine;
|
||||
|
||||
if ($function !~ /^NaturalDocs::/)
|
||||
{ $stackTrace .= ' of ' . $lastFile; };
|
||||
};
|
||||
|
||||
($lastPackage, $lastFile, $lastLine, $lastFunction) = ($package, $file, $line, $function);
|
||||
$i++;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
541
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/File.pm
Executable file
541
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/File.pm
Executable file
@ -0,0 +1,541 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::File
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to manage file access across platforms. Incorporates functions from various standard File:: packages, but more
|
||||
# importantly, works around the glorious suckage present in File::Spec, at least in version 0.82 and earlier. Read the "Why oh
|
||||
# why?" sections for why this package was necessary.
|
||||
#
|
||||
# Usage and Dependencies:
|
||||
#
|
||||
# - The package doesn't depend on any other Natural Docs packages and is ready to use immediately.
|
||||
#
|
||||
# - All functions except <CanonizePath()> assume that all parameters are canonized.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use File::Spec ();
|
||||
use File::Path ();
|
||||
use File::Copy ();
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::File;
|
||||
|
||||
|
||||
#
|
||||
# Function: CheckCompatibility
|
||||
#
|
||||
# Checks if the standard packages required by this one are up to snuff and dies if they aren't. This is done because I can't
|
||||
# tell which versions of File::Spec have splitpath just by the version numbers.
|
||||
#
|
||||
sub CheckCompatibility
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
eval {
|
||||
File::Spec->splitpath('');
|
||||
};
|
||||
|
||||
if ($@)
|
||||
{
|
||||
NaturalDocs::Error->SoftDeath("Natural Docs requires a newer version of File::Spec than you have. "
|
||||
. "You must either upgrade it or upgrade Perl.");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Path String Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: CanonizePath
|
||||
#
|
||||
# Takes a path and returns a logically simplified version of it.
|
||||
#
|
||||
# Why oh why?:
|
||||
#
|
||||
# Because File::Spec->canonpath doesn't strip quotes on Windows. So if you pass in "a b\c" or "a b"\c, they still end up as
|
||||
# different strings even though they're logically the same.
|
||||
#
|
||||
# It also doesn't remove things like "..", so "a/b/../c" doesn't simplify to "a/c" like it should.
|
||||
#
|
||||
sub CanonizePath #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
|
||||
if ($::OSNAME eq 'MSWin32')
|
||||
{
|
||||
# We don't have to use a smarter algorithm for dropping quotes because they're invalid characters for actual file and
|
||||
# directory names.
|
||||
$path =~ s/\"//g;
|
||||
};
|
||||
|
||||
$path = File::Spec->canonpath($path);
|
||||
|
||||
# Condense a/b/../c into a/c.
|
||||
|
||||
my $upDir = File::Spec->updir();
|
||||
if (index($path, $upDir) != -1)
|
||||
{
|
||||
my ($volume, $directoryString, $file) = $self->SplitPath($path);
|
||||
my @directories = $self->SplitDirectories($directoryString);
|
||||
|
||||
my $i = 1;
|
||||
while ($i < scalar @directories)
|
||||
{
|
||||
if ($i > 0 && $directories[$i] eq $upDir && $directories[$i - 1] ne $upDir)
|
||||
{
|
||||
splice(@directories, $i - 1, 2);
|
||||
$i--;
|
||||
}
|
||||
else
|
||||
{ $i++; };
|
||||
};
|
||||
|
||||
$directoryString = $self->JoinDirectories(@directories);
|
||||
$path = $self->JoinPath($volume, $directoryString, $file);
|
||||
};
|
||||
|
||||
return $path;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PathIsAbsolute
|
||||
#
|
||||
# Returns whether the passed path is absolute.
|
||||
#
|
||||
sub PathIsAbsolute #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
return File::Spec->file_name_is_absolute($path);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: JoinPath
|
||||
#
|
||||
# Creates a path from its elements.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# volume - The volume, such as the drive letter on Windows. Undef if none.
|
||||
# dirString - The directory string. Create with <JoinDirectories()> if necessary.
|
||||
# file - The file name, or undef if none.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The joined path.
|
||||
#
|
||||
sub JoinPath #(volume, dirString, $file)
|
||||
{
|
||||
my ($self, $volume, $dirString, $file) = @_;
|
||||
return File::Spec->catpath($volume, $dirString, $file);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: JoinPaths
|
||||
#
|
||||
# Joins two paths.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# basePath - May be a relative path, an absolute path, or undef.
|
||||
# extraPath - May be a relative path, a file, a relative path and file together, or undef.
|
||||
# noFileInExtra - Set this to true if extraPath is a relative path only, and doesn't have a file.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The joined path.
|
||||
#
|
||||
# Why oh why?:
|
||||
#
|
||||
# Because nothing in File::Spec will simply slap two paths together. They have to be split up for catpath/file, and rel2abs
|
||||
# requires the base to be absolute.
|
||||
#
|
||||
sub JoinPaths #(basePath, extraPath, noFileInExtra)
|
||||
{
|
||||
my ($self, $basePath, $extraPath, $noFileInExtra) = @_;
|
||||
|
||||
# If both are undef, it will return undef, which is what we want.
|
||||
if (!defined $basePath)
|
||||
{ return $extraPath; }
|
||||
elsif (!defined $extraPath)
|
||||
{ return $basePath; };
|
||||
|
||||
my ($baseVolume, $baseDirString, $baseFile) = File::Spec->splitpath($basePath, 1);
|
||||
my ($extraVolume, $extraDirString, $extraFile) = File::Spec->splitpath($extraPath, $noFileInExtra);
|
||||
|
||||
my @baseDirectories = $self->SplitDirectories($baseDirString);
|
||||
my @extraDirectories = $self->SplitDirectories($extraDirString);
|
||||
|
||||
my $fullDirString = $self->JoinDirectories(@baseDirectories, @extraDirectories);
|
||||
|
||||
my $fullPath = File::Spec->catpath($baseVolume, $fullDirString, $extraFile);
|
||||
|
||||
return $self->CanonizePath($fullPath);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SplitPath
|
||||
#
|
||||
# Takes a path and returns its elements.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# path - The path to split.
|
||||
# noFile - Set to true if the path doesn't have a file at the end.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The array ( volume, directoryString, file ). If any don't apply, they will be undef. Use <SplitDirectories()> to split the
|
||||
# directory string if desired.
|
||||
#
|
||||
# Why oh Why?:
|
||||
#
|
||||
# Because File::Spec->splitpath may leave a trailing slash/backslash/whatever on the directory string, which makes
|
||||
# it a bit hard to match it with results from File::Spec->catdir.
|
||||
#
|
||||
sub SplitPath #(path, noFile)
|
||||
{
|
||||
my ($self, $path, $noFile) = @_;
|
||||
|
||||
my @segments = File::Spec->splitpath($path, $noFile);
|
||||
|
||||
if (!length $segments[0])
|
||||
{ $segments[0] = undef; };
|
||||
if (!length $segments[2])
|
||||
{ $segments[2] = undef; };
|
||||
|
||||
$segments[1] = File::Spec->catdir( File::Spec->splitdir($segments[1]) );
|
||||
|
||||
return @segments;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: JoinDirectories
|
||||
#
|
||||
# Creates a directory string from an array of directory names.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# directory - A directory name. There may be as many of these as desired.
|
||||
#
|
||||
sub JoinDirectories #(directory, directory, ...)
|
||||
{
|
||||
my ($self, @directories) = @_;
|
||||
return File::Spec->catdir(@directories);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SplitDirectories
|
||||
#
|
||||
# Takes a string of directories and returns an array of its elements.
|
||||
#
|
||||
# Why oh why?:
|
||||
#
|
||||
# Because File::Spec->splitdir might leave an empty element at the end of the array, which screws up both joining in
|
||||
# <ConvertToURL> and navigation in <MakeRelativePath>.
|
||||
#
|
||||
sub SplitDirectories #(directoryString)
|
||||
{
|
||||
my ($self, $directoryString) = @_;
|
||||
|
||||
my @directories = File::Spec->splitdir($directoryString);
|
||||
|
||||
if (!length $directories[-1])
|
||||
{ pop @directories; };
|
||||
|
||||
return @directories;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: MakeRelativePath
|
||||
#
|
||||
# Takes two paths and returns a relative path between them.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# basePath - The starting path. May be relative or absolute, so long as the target path is as well.
|
||||
# targetPath - The target path. May be relative or absolute, so long as the base path is as well.
|
||||
#
|
||||
# If both paths are relative, they are assumed to be relative to the same base.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The target path relative to base.
|
||||
#
|
||||
# Why oh why?:
|
||||
#
|
||||
# First, there's nothing that gives a relative path between two relative paths.
|
||||
#
|
||||
# Second, if target and base are absolute but on different volumes, File::Spec->abs2rel creates a totally non-functional
|
||||
# relative path. It should return the target as is, since there is no relative path.
|
||||
#
|
||||
# Third, File::Spec->abs2rel between absolute paths on the same volume, at least on Windows, leaves the drive letter
|
||||
# on. So abs2rel('a:\b\c\d', 'a:\b') returns 'a:c\d' instead of the expected 'c\d'. That makes no sense whatsoever. It's
|
||||
# not like it was designed to handle only directory names, either; the documentation says 'path' and the code seems to
|
||||
# explicitly handle it. There's just an 'unless' in there that tacks on the volume, defeating the purpose of a *relative* path
|
||||
# and making the function worthless.
|
||||
#
|
||||
sub MakeRelativePath #(basePath, targetPath)
|
||||
{
|
||||
my ($self, $basePath, $targetPath) = @_;
|
||||
|
||||
my ($baseVolume, $baseDirString, $baseFile) = $self->SplitPath($basePath, 1);
|
||||
my ($targetVolume, $targetDirString, $targetFile) = $self->SplitPath($targetPath);
|
||||
|
||||
# If the volumes are different, there is no possible relative path.
|
||||
if ($targetVolume ne $baseVolume)
|
||||
{ return $targetPath; };
|
||||
|
||||
my @baseDirectories = $self->SplitDirectories($baseDirString);
|
||||
my @targetDirectories = $self->SplitDirectories($targetDirString);
|
||||
|
||||
# Skip the parts of the path that are the same.
|
||||
while (scalar @baseDirectories && @targetDirectories && $baseDirectories[0] eq $targetDirectories[0])
|
||||
{
|
||||
shift @baseDirectories;
|
||||
shift @targetDirectories;
|
||||
};
|
||||
|
||||
# Back out of the base path until it reaches where they were similar.
|
||||
for (my $i = 0; $i < scalar @baseDirectories; $i++)
|
||||
{
|
||||
unshift @targetDirectories, File::Spec->updir();
|
||||
};
|
||||
|
||||
$targetDirString = $self->JoinDirectories(@targetDirectories);
|
||||
|
||||
return File::Spec->catpath(undef, $targetDirString, $targetFile);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsSubPathOf
|
||||
#
|
||||
# Returns whether the path is a descendant of another path.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# base - The base path to test against.
|
||||
# path - The possible subpath to test.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether path is a descendant of base.
|
||||
#
|
||||
sub IsSubPathOf #(base, path)
|
||||
{
|
||||
my ($self, $base, $path) = @_;
|
||||
|
||||
# This is a quick test that should find a false quickly.
|
||||
if ($base eq substr($path, 0, length($base)))
|
||||
{
|
||||
# This doesn't guarantee true, because it could be "C:\A B" and "C:\A B C\File". So we test for it by seeing if the last
|
||||
# directory in base is the same as the equivalent directory in path.
|
||||
|
||||
my ($baseVolume, $baseDirString, $baseFile) = NaturalDocs::File->SplitPath($base, 1);
|
||||
my @baseDirectories = NaturalDocs::File->SplitDirectories($baseDirString);
|
||||
|
||||
my ($pathVolume, $pathDirString, $pathFile) = NaturalDocs::File->SplitPath($path);
|
||||
my @pathDirectories = NaturalDocs::File->SplitDirectories($pathDirString);
|
||||
|
||||
return ( $baseDirectories[-1] eq $pathDirectories[ scalar @baseDirectories - 1 ] );
|
||||
}
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ConvertToURL
|
||||
#
|
||||
# Takes a relative path and converts it from the native format to a relative URL. Note that it _doesn't_ convert special characters
|
||||
# to amp chars.
|
||||
#
|
||||
sub ConvertToURL #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
|
||||
my ($pathVolume, $pathDirString, $pathFile) = $self->SplitPath($path);
|
||||
my @pathDirectories = $self->SplitDirectories($pathDirString);
|
||||
|
||||
my $i = 0;
|
||||
while ($i < scalar @pathDirectories && $pathDirectories[$i] eq File::Spec->updir())
|
||||
{
|
||||
$pathDirectories[$i] = '..';
|
||||
$i++;
|
||||
};
|
||||
|
||||
return join('/', @pathDirectories, $pathFile);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: NoUpwards
|
||||
#
|
||||
# Takes an array of directory entries and returns one without all the entries that refer to the parent directory, such as '.' and '..'.
|
||||
#
|
||||
sub NoUpwards #(array)
|
||||
{
|
||||
my ($self, @array) = @_;
|
||||
return File::Spec->no_upwards(@array);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: NoFileName
|
||||
#
|
||||
# Takes a path and returns a version without the file name. Useful for sending paths to <CreatePath()>.
|
||||
#
|
||||
sub NoFileName #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
|
||||
my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
|
||||
|
||||
return File::Spec->catpath($pathVolume, $pathDirString, undef);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: NoExtension
|
||||
#
|
||||
# Returns the path without an extension.
|
||||
#
|
||||
sub NoExtension #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
|
||||
my $extension = $self->ExtensionOf($path);
|
||||
|
||||
if ($extension)
|
||||
{ $path = substr($path, 0, length($path) - length($extension) - 1); };
|
||||
|
||||
return $path;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ExtensionOf
|
||||
#
|
||||
# Returns the extension of the passed path, or undef if none.
|
||||
#
|
||||
sub ExtensionOf #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
|
||||
my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
|
||||
|
||||
# We need the leading dot in the regex so files that start with a dot but don't have an extension count as extensionless files.
|
||||
if ($pathFile =~ /.\.([^\.]+)$/)
|
||||
{ return $1; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsCaseSensitive
|
||||
#
|
||||
# Returns whether the current platform has case-sensitive paths.
|
||||
#
|
||||
sub IsCaseSensitive
|
||||
{
|
||||
return !(File::Spec->case_tolerant());
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Disk Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: CreatePath
|
||||
#
|
||||
# Creates a directory tree corresponding to the passed path, regardless of how many directories do or do not already exist.
|
||||
# Do _not_ include a file name in the path. Use <NoFileName()> first if you need to.
|
||||
#
|
||||
sub CreatePath #(path)
|
||||
{
|
||||
my ($self, $path) = @_;
|
||||
File::Path::mkpath($path);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: RemoveEmptyTree
|
||||
#
|
||||
# Removes an empty directory tree. The passed directory will be removed if it's empty, and it will keep removing its parents
|
||||
# until it reaches one that's not empty or a set limit.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# path - The path to start from. It will try to remove this directory and work it's way down.
|
||||
# limit - The path to stop at if it doesn't find any non-empty directories first. This path will *not* be removed.
|
||||
#
|
||||
sub RemoveEmptyTree #(path, limit)
|
||||
{
|
||||
my ($self, $path, $limit) = @_;
|
||||
|
||||
my ($volume, $directoryString) = $self->SplitPath($path, 1);
|
||||
my @directories = $self->SplitDirectories($directoryString);
|
||||
|
||||
my $directory = $path;
|
||||
|
||||
while (-d $directory && $directory ne $limit)
|
||||
{
|
||||
opendir FH_ND_FILE, $directory;
|
||||
my @entries = readdir FH_ND_FILE;
|
||||
closedir FH_ND_FILE;
|
||||
|
||||
@entries = $self->NoUpwards(@entries);
|
||||
|
||||
if (scalar @entries || !rmdir($directory))
|
||||
{ last; };
|
||||
|
||||
pop @directories;
|
||||
$directoryString = $self->JoinDirectories(@directories);
|
||||
$directory = $self->JoinPath($volume, $directoryString);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Copy
|
||||
#
|
||||
# Copies a file from one path to another. If the destination file exists, it is overwritten.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# source - The file to copy.
|
||||
# destination - The destination to copy to.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether it succeeded
|
||||
#
|
||||
sub Copy #(source, destination) => bool
|
||||
{
|
||||
my ($self, $source, $destination) = @_;
|
||||
return File::Copy::copy($source, $destination);
|
||||
};
|
||||
|
||||
|
||||
1;
|
398
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ImageReferenceTable.pm
Executable file
398
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ImageReferenceTable.pm
Executable file
@ -0,0 +1,398 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ImageReferenceTable
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A <NaturalDocs::SourceDB>-based package that manages all the image references appearing in source files.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use NaturalDocs::ImageReferenceTable::String;
|
||||
use NaturalDocs::ImageReferenceTable::Reference;
|
||||
|
||||
|
||||
package NaturalDocs::ImageReferenceTable;
|
||||
|
||||
use base 'NaturalDocs::SourceDB::Extension';
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information
|
||||
|
||||
#
|
||||
# Topic: Usage
|
||||
#
|
||||
# - <NaturalDocs::Project> and <NaturalDocs::SourceDB> must be initialized before this package can be used.
|
||||
#
|
||||
# - Call <Register()> before using.
|
||||
#
|
||||
#
|
||||
# Topic: Programming Notes
|
||||
#
|
||||
# When working on this code, remember that there are three things it has to juggle.
|
||||
#
|
||||
# - The information in <NaturalDocs::SourceDB>.
|
||||
# - Image file references in <NaturalDocs::Project>.
|
||||
# - Source file rebuilding on changes.
|
||||
#
|
||||
# Managing the actual image files will be handled between <NaturalDocs::Project> and the <NaturalDocs::Builder>
|
||||
# sub-packages.
|
||||
#
|
||||
#
|
||||
# Topic: Implementation
|
||||
#
|
||||
# Managing image references is simpler than managing the references in <NaturalDocs::SymbolTable>. In SymbolTable,
|
||||
# you have to worry about reference targets popping into and out of existence. A link may go to a file that hasn't been
|
||||
# reparsed yet and the target may no longer exist. We have to deal with that when we know it, which may be after the
|
||||
# reference's file was parsed. Also, a new definition may appear that serves as a better interpretation of a link than its
|
||||
# current target, and again we may only know that after the reference's file has been parsed already. So we have to deal
|
||||
# with scores and potential symbols and each symbol knowing exactly what links to it and so forth.
|
||||
#
|
||||
# Not so with image references. All possible targets (all possible image files) are known by <NaturalDocs::Project> early
|
||||
# on and will remain consistent throughout execution. So because of that, we can get away with only storing reference
|
||||
# counts with each image and determining exactly where a reference points to as we find them.
|
||||
#
|
||||
# Reference counts are stored with the image file information in <NaturalDocs::Project>. However, it is not loaded and
|
||||
# saved to disk by it. Rather, it is regenerated by this package when it loads <ImageReferenceTable.nd>.
|
||||
# NaturalDocs::Project only stores the last modification time (so it can add files to the build list if they've changed) and
|
||||
# whether it had any references at all on the last run (so it knows whether it should care if they've changed.)
|
||||
# ImageReferenceTable.nd stores each reference's target, width, and height. Whether their interpretations have changed is
|
||||
# dealt with in the <Load()> function, again since the list of targets (image files) is constant.
|
||||
#
|
||||
# The package is based on <NaturalDocs::SourceDB>, so read it's documentation for more information on how it works.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
|
||||
#
|
||||
# var: extensionID
|
||||
# The <ExtensionID> granted by <NaturalDocs::SourceDB>.
|
||||
#
|
||||
my $extensionID;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Files
|
||||
|
||||
|
||||
#
|
||||
# File: ImageReferenceTable.nd
|
||||
#
|
||||
# The data file which stores all the image references from the last run of Natural Docs.
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# > [Standard Binary Header]
|
||||
#
|
||||
# It starts with the standard binary header from <NaturalDocs::BinaryFile>.
|
||||
#
|
||||
# > [Image Reference String or undef]
|
||||
# > [UString16: target file]
|
||||
# > [UInt16: target width or 0]
|
||||
# > [UInt16: target height or 0]
|
||||
#
|
||||
# For each <ImageReferenceString>, it's target, width, and height are stored. The target is needed so we can tell if it
|
||||
# changed from the last run, and the dimensions are needed because if the target hasn't changed but the file's dimensions
|
||||
# have, the source files need to be rebuilt.
|
||||
#
|
||||
# <ImageReferenceStrings> are encoded by <NaturalDocs::ImageReferenceTable::String>.
|
||||
#
|
||||
# > [UString16: definition file or undef] ...
|
||||
#
|
||||
# Then comes a series of UString16s for all the files that define the reference until it hits an undef.
|
||||
#
|
||||
# This whole series is repeated for each <ImageReferenceString> until it hits an undef.
|
||||
#
|
||||
# Revisions:
|
||||
#
|
||||
# 1.52:
|
||||
#
|
||||
# - AString16s were changed to UString16s.
|
||||
#
|
||||
# 1.4:
|
||||
#
|
||||
# - The file was added to Natural Docs.
|
||||
#
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Register
|
||||
# Registers the package with <NaturalDocs::SourceDB>.
|
||||
#
|
||||
sub Register
|
||||
{
|
||||
my $self = shift;
|
||||
$extensionID = NaturalDocs::SourceDB->RegisterExtension($self, 0);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Load
|
||||
#
|
||||
# Loads the data from <ImageReferenceTable.nd>. Returns whether it was successful.
|
||||
#
|
||||
sub Load # => bool
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (NaturalDocs::Settings->RebuildData())
|
||||
{ return 0; };
|
||||
|
||||
my $version = NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') );
|
||||
my $fileIsOkay;
|
||||
|
||||
if (defined $version)
|
||||
{
|
||||
if (NaturalDocs::Version->CheckFileFormat($version, NaturalDocs::Version->FromString('1.52')))
|
||||
{ $fileIsOkay = 1; }
|
||||
else
|
||||
{ NaturalDocs::BinaryFile->Close(); };
|
||||
};
|
||||
|
||||
if (!$fileIsOkay)
|
||||
{ return 0; };
|
||||
|
||||
|
||||
# [Image Reference String or undef]
|
||||
while (my $referenceString = NaturalDocs::ImageReferenceTable::String->FromBinaryFile())
|
||||
{
|
||||
NaturalDocs::SourceDB->AddItem($extensionID, $referenceString,
|
||||
NaturalDocs::ImageReferenceTable::Reference->New());
|
||||
|
||||
# [UString16: target file]
|
||||
# [UInt16: target width or 0]
|
||||
# [UInt16: target height or 0]
|
||||
|
||||
my $targetFile = NaturalDocs::BinaryFile->GetUString16();
|
||||
my $width = NaturalDocs::BinaryFile->GetUInt16();
|
||||
my $height = NaturalDocs::BinaryFile->GetUInt16();
|
||||
|
||||
my $newTargetFile = $self->SetReferenceTarget($referenceString);
|
||||
my $newWidth;
|
||||
my $newHeight;
|
||||
|
||||
if ($newTargetFile)
|
||||
{
|
||||
NaturalDocs::Project->AddImageFileReference($newTargetFile);
|
||||
($newWidth, $newHeight) = NaturalDocs::Project->ImageFileDimensions($newTargetFile);
|
||||
};
|
||||
|
||||
my $rebuildDefinitions = ($newTargetFile ne $targetFile || $newWidth != $width || $newHeight != $height);
|
||||
|
||||
|
||||
# [UString16: definition file or undef] ...
|
||||
while (my $definitionFile = NaturalDocs::BinaryFile->GetUString16())
|
||||
{
|
||||
NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $definitionFile);
|
||||
|
||||
if ($rebuildDefinitions)
|
||||
{ NaturalDocs::Project->RebuildFile($definitionFile); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
NaturalDocs::BinaryFile->Close();
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Save
|
||||
#
|
||||
# Saves the data to <ImageReferenceTable.nd>.
|
||||
#
|
||||
sub Save
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $references = NaturalDocs::SourceDB->GetAllItemsHashRef($extensionID);
|
||||
|
||||
NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') );
|
||||
|
||||
while (my ($referenceString, $referenceObject) = each %$references)
|
||||
{
|
||||
# [Image Reference String or undef]
|
||||
# [UString16: target file]
|
||||
# [UInt16: target width or 0]
|
||||
# [UInt16: target height or 0]
|
||||
|
||||
NaturalDocs::ImageReferenceTable::String->ToBinaryFile($referenceString);
|
||||
|
||||
my $target = $referenceObject->Target();
|
||||
my ($width, $height);
|
||||
|
||||
if ($target)
|
||||
{ ($width, $height) = NaturalDocs::Project->ImageFileDimensions($target); };
|
||||
|
||||
NaturalDocs::BinaryFile->WriteUString16( $referenceObject->Target() );
|
||||
NaturalDocs::BinaryFile->WriteUInt16( ($width || 0) );
|
||||
NaturalDocs::BinaryFile->WriteUInt16( ($height || 0) );
|
||||
|
||||
# [UString16: definition file or undef] ...
|
||||
|
||||
my $definitions = $referenceObject->GetAllDefinitionsHashRef();
|
||||
|
||||
foreach my $definition (keys %$definitions)
|
||||
{ NaturalDocs::BinaryFile->WriteUString16($definition); };
|
||||
|
||||
NaturalDocs::BinaryFile->WriteUString16(undef);
|
||||
};
|
||||
|
||||
NaturalDocs::ImageReferenceTable::String->ToBinaryFile(undef);
|
||||
|
||||
NaturalDocs::BinaryFile->Close();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddReference
|
||||
#
|
||||
# Adds a new image reference.
|
||||
#
|
||||
sub AddReference #(FileName file, string referenceText)
|
||||
{
|
||||
my ($self, $file, $referenceText) = @_;
|
||||
|
||||
my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($file, $referenceText);
|
||||
|
||||
if (!NaturalDocs::SourceDB->HasItem($extensionID, $referenceString))
|
||||
{
|
||||
my $referenceObject = NaturalDocs::ImageReferenceTable::Reference->New();
|
||||
NaturalDocs::SourceDB->AddItem($extensionID, $referenceString, $referenceObject);
|
||||
|
||||
my $target = $self->SetReferenceTarget($referenceString);
|
||||
if ($target)
|
||||
{ NaturalDocs::Project->AddImageFileReference($target); };
|
||||
};
|
||||
|
||||
NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $file);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnDeletedDefinition
|
||||
#
|
||||
# Called for each definition deleted by <NaturalDocs::SourceDB>. This is called *after* the definition has been deleted from
|
||||
# the database, so don't expect to be able to read it.
|
||||
#
|
||||
sub OnDeletedDefinition #(ImageReferenceString referenceString, FileName file, bool wasLastDefinition)
|
||||
{
|
||||
my ($self, $referenceString, $file, $wasLastDefinition) = @_;
|
||||
|
||||
if ($wasLastDefinition)
|
||||
{
|
||||
my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
|
||||
my $target = $referenceObject->Target();
|
||||
|
||||
if ($target)
|
||||
{ NaturalDocs::Project->DeleteImageFileReference($target); };
|
||||
|
||||
NaturalDocs::SourceDB->DeleteItem($extensionID, $referenceString);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetReferenceTarget
|
||||
#
|
||||
# Returns the image file the reference resolves to, or undef if none.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The source <FileName> the reference appears in.
|
||||
# text - The reference text.
|
||||
#
|
||||
sub GetReferenceTarget #(FileName sourceFile, string text) => FileName
|
||||
{
|
||||
my ($self, $sourceFile, $text) = @_;
|
||||
|
||||
my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($sourceFile, $text);
|
||||
my $reference = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
|
||||
|
||||
if (!defined $reference)
|
||||
{ return undef; }
|
||||
else
|
||||
{ return $reference->Target(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetReferenceTarget
|
||||
#
|
||||
# Determines the best target for the passed <ImageReferenceString> and sets it on the
|
||||
# <NaturalDocs::ImageReferenceTable::Reference> object. Returns the new target <FileName>. Does *not* add any source
|
||||
# files to the bulid list.
|
||||
#
|
||||
sub SetReferenceTarget #(ImageReferenceString referenceString) => FileName
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
|
||||
my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString);
|
||||
my ($sourcePath, $text) = NaturalDocs::ImageReferenceTable::String->InformationOf($referenceString);
|
||||
|
||||
|
||||
# Try the path relative to the source file first.
|
||||
|
||||
my $target;
|
||||
|
||||
my $imageFile = NaturalDocs::File->JoinPaths($sourcePath, $text);
|
||||
my $exists = NaturalDocs::Project->ImageFileExists($imageFile);
|
||||
|
||||
|
||||
# Then try relative image directories.
|
||||
|
||||
if (!$exists)
|
||||
{
|
||||
my $relativeImageDirectories = NaturalDocs::Settings->RelativeImageDirectories();
|
||||
|
||||
for (my $i = 0; $i < scalar @$relativeImageDirectories && !$exists; $i++)
|
||||
{
|
||||
$imageFile = NaturalDocs::File->JoinPaths($sourcePath, $relativeImageDirectories->[$i], 1);
|
||||
$imageFile = NaturalDocs::File->JoinPaths($imageFile, $text);
|
||||
|
||||
$exists = NaturalDocs::Project->ImageFileExists($imageFile);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# Then try absolute image directories.
|
||||
|
||||
if (!$exists)
|
||||
{
|
||||
my $imageDirectories = NaturalDocs::Settings->ImageDirectories();
|
||||
|
||||
for (my $i = 0; $i < scalar @$imageDirectories && !$exists; $i++)
|
||||
{
|
||||
$imageFile = NaturalDocs::File->JoinPaths($imageDirectories->[$i], $text);
|
||||
$exists = NaturalDocs::Project->ImageFileExists($imageFile);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
if ($exists)
|
||||
{ $target = NaturalDocs::Project->ImageFileCapitalization($imageFile); };
|
||||
#else leave it as undef.
|
||||
|
||||
$referenceObject->SetTarget($target);
|
||||
return $target;
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,45 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ImageReferenceTable::Reference
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class for references being tracked in <NaturalDocs::SourceDB>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::ImageReferenceTable::Reference;
|
||||
|
||||
use base 'NaturalDocs::SourceDB::Item';
|
||||
|
||||
|
||||
use NaturalDocs::DefineMembers 'TARGET', 'Target()', 'SetTarget()',
|
||||
'NEEDS_REBUILD', 'NeedsRebuild()', 'SetNeedsRebuild()';
|
||||
|
||||
|
||||
#
|
||||
# Variables: Members
|
||||
#
|
||||
# The following constants are indexes into the object array.
|
||||
#
|
||||
# TARGET - The image <FileName> this reference resolves to, or undef if none.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Functions: Member Functions
|
||||
#
|
||||
# Target - Returns the image <FileName> this reference resolves to, or undef if none.
|
||||
# SetTarget - Replaces the image <FileName> this reference resolves to, or undef if none.
|
||||
#
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,111 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ImageReferenceTable::String
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package for creating and managing <ImageReferenceStrings>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::ImageReferenceTable::String;
|
||||
|
||||
|
||||
#
|
||||
# Type: ImageReferenceString
|
||||
#
|
||||
# A string representing a unique image reference. It's composed of the reference text and the directory of the source file.
|
||||
# The source file name itself isn't included because two files in the same directory with the same reference text will always go
|
||||
# to the same targets.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: Make
|
||||
#
|
||||
# Converts a source <FileName> and the reference text to an <ImageReferenceString>.
|
||||
#
|
||||
sub Make #(FileName sourceFile, string text) => ImageReferenceString
|
||||
{
|
||||
my ($self, $sourceFile, $text) = @_;
|
||||
|
||||
my $path = NaturalDocs::File->NoFileName($sourceFile);
|
||||
|
||||
# Condense whitespace and remove any separator characters.
|
||||
$path =~ tr/ \t\r\n\x1C/ /s;
|
||||
$text =~ tr/ \t\r\n\x1C/ /s;
|
||||
|
||||
return $path . "\x1C" . $text;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: InformationOf
|
||||
#
|
||||
# Returns the information contained in the <ImageReferenceString> as the array ( path, text ).
|
||||
#
|
||||
sub InformationOf #(ImageReferenceString referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
return split(/\x1C/, $referenceString);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToBinaryFile
|
||||
#
|
||||
# Writes an <ImageReferenceString> to <NaturalDocs::BinaryFile>. Can also encode an undef.
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# > [UString16: path] [UString16: reference text] ...
|
||||
#
|
||||
# Undef is represented by the first UString16 being undef.
|
||||
#
|
||||
sub ToBinaryFile #(ImageReferenceString referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
|
||||
if (defined $referenceString)
|
||||
{
|
||||
my ($path, $text) = split(/\x1C/, $referenceString);
|
||||
|
||||
NaturalDocs::BinaryFile->WriteUString16($path);
|
||||
NaturalDocs::BinaryFile->WriteUString16($text);
|
||||
}
|
||||
else
|
||||
{
|
||||
NaturalDocs::BinaryFile->WriteUString16(undef);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromBinaryFile
|
||||
#
|
||||
# Loads an <ImageReferenceString> or undef from <NaturalDocs::BinaryFile> and returns it.
|
||||
#
|
||||
sub FromBinaryFile
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $path = NaturalDocs::BinaryFile->GetUString16();
|
||||
|
||||
if (!defined $path)
|
||||
{ return undef; };
|
||||
|
||||
my $text = NaturalDocs::BinaryFile->GetUString16();
|
||||
|
||||
return $path . "\x1C" . $text;
|
||||
};
|
||||
|
||||
|
||||
1;
|
1481
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages.pm
Executable file
1481
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages.pm
Executable file
File diff suppressed because it is too large
Load Diff
1487
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/ActionScript.pm
Executable file
1487
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/ActionScript.pm
Executable file
File diff suppressed because it is too large
Load Diff
39
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Ada.pm
Executable file
39
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Ada.pm
Executable file
@ -0,0 +1,39 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Ada
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A subclass to handle the language variations of Ada
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Ada;
|
||||
|
||||
use base 'NaturalDocs::Languages::Simple';
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseParameterLine
|
||||
# Overridden because Ada uses Pascal-style parameters
|
||||
#
|
||||
sub ParseParameterLine #(...)
|
||||
{
|
||||
my ($self, @params) = @_;
|
||||
return $self->SUPER::ParsePascalParameterLine(@params);
|
||||
};
|
||||
|
||||
sub TypeBeforeParameter
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
1;
|
817
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Advanced.pm
Executable file
817
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Advanced.pm
Executable file
@ -0,0 +1,817 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Advanced
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# The base class for all languages that have full support in Natural Docs. Each one will have a custom parser capable
|
||||
# of documenting undocumented aspects of the code.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use NaturalDocs::Languages::Advanced::Scope;
|
||||
use NaturalDocs::Languages::Advanced::ScopeChange;
|
||||
|
||||
package NaturalDocs::Languages::Advanced;
|
||||
|
||||
use base 'NaturalDocs::Languages::Base';
|
||||
|
||||
|
||||
#############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are used as indexes.
|
||||
#
|
||||
# TOKENS - An arrayref of tokens used in all the <Parsing Functions>.
|
||||
# SCOPE_STACK - An arrayref of <NaturalDocs::Languages::Advanced::Scope> objects serving as a scope stack for parsing.
|
||||
# There will always be one available, with a symbol of undef, for the top level.
|
||||
# SCOPE_RECORD - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChange> objects, as generated by the scope
|
||||
# stack. If there is more than one change per line, only the last is stored.
|
||||
# AUTO_TOPICS - An arrayref of <NaturalDocs::Parser::ParsedTopics> generated automatically from the code.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'TOKENS', 'SCOPE_STACK', 'SCOPE_RECORD', 'AUTO_TOPICS';
|
||||
|
||||
|
||||
#############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# name - The name of the language.
|
||||
#
|
||||
sub New #(name)
|
||||
{
|
||||
my ($package, @parameters) = @_;
|
||||
|
||||
my $object = $package->SUPER::New(@parameters);
|
||||
$object->[TOKENS] = undef;
|
||||
$object->[SCOPE_STACK] = undef;
|
||||
$object->[SCOPE_RECORD] = undef;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Tokens
|
||||
# Returns the tokens found by <ParseForCommentsAndTokens()>.
|
||||
sub Tokens
|
||||
{ return $_[0]->[TOKENS]; };
|
||||
|
||||
# Function: SetTokens
|
||||
# Replaces the tokens.
|
||||
sub SetTokens #(tokens)
|
||||
{ $_[0]->[TOKENS] = $_[1]; };
|
||||
|
||||
# Function: ClearTokens
|
||||
# Resets the token list. You may want to do this after parsing is over to save memory.
|
||||
sub ClearTokens
|
||||
{ $_[0]->[TOKENS] = undef; };
|
||||
|
||||
# Function: AutoTopics
|
||||
# Returns the arrayref of automatically generated topics, or undef if none.
|
||||
sub AutoTopics
|
||||
{ return $_[0]->[AUTO_TOPICS]; };
|
||||
|
||||
# Function: AddAutoTopic
|
||||
# Adds a <NaturalDocs::Parser::ParsedTopic> to <AutoTopics()>.
|
||||
sub AddAutoTopic #(topic)
|
||||
{
|
||||
my ($self, $topic) = @_;
|
||||
if (!defined $self->[AUTO_TOPICS])
|
||||
{ $self->[AUTO_TOPICS] = [ ]; };
|
||||
push @{$self->[AUTO_TOPICS]}, $topic;
|
||||
};
|
||||
|
||||
# Function: ClearAutoTopics
|
||||
# Resets the automatic topic list. Not necessary if you call <ParseForCommentsAndTokens()>.
|
||||
sub ClearAutoTopics
|
||||
{ $_[0]->[AUTO_TOPICS] = undef; };
|
||||
|
||||
# Function: ScopeRecord
|
||||
# Returns an arrayref of <NaturalDocs::Languages::Advanced::ScopeChange> objects describing how and when the scope
|
||||
# changed thoughout the file. There will always be at least one entry, which will be for line 1 and undef as the scope.
|
||||
sub ScopeRecord
|
||||
{ return $_[0]->[SCOPE_RECORD]; };
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Group: Parsing Functions
|
||||
#
|
||||
# These functions are good general language building blocks. Use them to create your language-specific parser.
|
||||
#
|
||||
# All functions work on <Tokens()> and assume it is set by <ParseForCommentsAndTokens()>.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseForCommentsAndTokens
|
||||
#
|
||||
# Loads the passed file, sends all appropriate comments to <NaturalDocs::Parser->OnComment()>, and breaks the rest into
|
||||
# an arrayref of tokens. Tokens are defined as
|
||||
#
|
||||
# - All consecutive alphanumeric and underscore characters.
|
||||
# - All consecutive whitespace.
|
||||
# - A single line break. It will always be "\n"; you don't have to worry about platform differences.
|
||||
# - A single character not included above, which is usually a symbol. Multiple consecutive ones each get their own token.
|
||||
#
|
||||
# The result will be placed in <Tokens()>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The source <FileName> to load and parse.
|
||||
# lineCommentSymbols - An arrayref of symbols that designate line comments, or undef if none.
|
||||
# blockCommentSymbols - An arrayref of symbol pairs that designate multiline comments, or undef if none. Symbol pairs are
|
||||
# designated as two consecutive array entries, the opening symbol appearing first.
|
||||
# javadocLineCommentSymbols - An arrayref of symbols that designate the start of a JavaDoc comment, or undef if none.
|
||||
# javadocBlockCommentSymbols - An arrayref of symbol pairs that designate multiline JavaDoc comments, or undef if none.
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# - This function automatically calls <ClearAutoTopics()> and <ClearScopeStack()>. You only need to call those functions
|
||||
# manually if you override this one.
|
||||
# - To save parsing time, all comment lines sent to <NaturalDocs::Parser->OnComment()> will be replaced with blank lines
|
||||
# in <Tokens()>. It's all the same to most languages.
|
||||
#
|
||||
sub ParseForCommentsAndTokens #(FileName sourceFile, string[] lineCommentSymbols, string[] blockCommentSymbols, string[] javadocLineCommentSymbols, string[] javadocBlockCommentSymbols)
|
||||
{
|
||||
my ($self, $sourceFile, $lineCommentSymbols, $blockCommentSymbols,
|
||||
$javadocLineCommentSymbols, $javadocBlockCommentSymbols) = @_;
|
||||
|
||||
open(SOURCEFILEHANDLE, '<' . $sourceFile)
|
||||
or die "Couldn't open input file " . $sourceFile . "\n";
|
||||
|
||||
my $lineReader = NaturalDocs::LineReader->New(\*SOURCEFILEHANDLE);
|
||||
|
||||
my $tokens = [ ];
|
||||
$self->SetTokens($tokens);
|
||||
|
||||
# For convenience.
|
||||
$self->ClearAutoTopics();
|
||||
$self->ClearScopeStack();
|
||||
|
||||
|
||||
# Load and preprocess the file
|
||||
|
||||
my @lines = $lineReader->GetAll();
|
||||
close(SOURCEFILEHANDLE);
|
||||
|
||||
$self->PreprocessFile(\@lines);
|
||||
|
||||
|
||||
# Go through the file
|
||||
|
||||
my $lineIndex = 0;
|
||||
|
||||
while ($lineIndex < scalar @lines)
|
||||
{
|
||||
my $line = $lines[$lineIndex];
|
||||
|
||||
my @commentLines;
|
||||
my $commentLineNumber;
|
||||
my $isJavaDoc;
|
||||
my $closingSymbol;
|
||||
|
||||
|
||||
# Retrieve single line comments. This leaves $lineIndex at the next line.
|
||||
|
||||
if ( ($isJavaDoc = $self->StripOpeningJavaDocSymbols(\$line, $javadocLineCommentSymbols)) ||
|
||||
$self->StripOpeningSymbols(\$line, $lineCommentSymbols))
|
||||
{
|
||||
$commentLineNumber = $lineIndex + 1;
|
||||
|
||||
do
|
||||
{
|
||||
push @commentLines, $line;
|
||||
push @$tokens, "\n";
|
||||
|
||||
$lineIndex++;
|
||||
|
||||
if ($lineIndex >= scalar @lines)
|
||||
{ goto EndDo; };
|
||||
|
||||
$line = $lines[$lineIndex];
|
||||
}
|
||||
while ($self->StripOpeningSymbols(\$line, $lineCommentSymbols));
|
||||
|
||||
EndDo: # I hate Perl sometimes.
|
||||
}
|
||||
|
||||
|
||||
# Retrieve multiline comments. This leaves $lineIndex at the next line.
|
||||
|
||||
elsif ( ($isJavaDoc = $self->StripOpeningJavaDocBlockSymbols(\$line, $javadocBlockCommentSymbols)) ||
|
||||
($closingSymbol = $self->StripOpeningBlockSymbols(\$line, $blockCommentSymbols)) )
|
||||
{
|
||||
$commentLineNumber = $lineIndex + 1;
|
||||
|
||||
if ($isJavaDoc)
|
||||
{ $closingSymbol = $isJavaDoc; };
|
||||
|
||||
# Note that it is possible for a multiline comment to start correctly but not end so. We want those comments to stay in
|
||||
# the code. For example, look at this prototype with this splint annotation:
|
||||
#
|
||||
# int get_array(integer_t id,
|
||||
# /*@out@*/ array_t array);
|
||||
#
|
||||
# The annotation starts correctly but doesn't end so because it is followed by code on the same line.
|
||||
|
||||
my ($lineRemainder, $isMultiLine);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
$lineRemainder = $self->StripClosingSymbol(\$line, $closingSymbol);
|
||||
|
||||
push @commentLines, $line;
|
||||
|
||||
# If we found an end comment symbol...
|
||||
if (defined $lineRemainder)
|
||||
{ last; };
|
||||
|
||||
push @$tokens, "\n";
|
||||
$lineIndex++;
|
||||
$isMultiLine = 1;
|
||||
|
||||
if ($lineIndex >= scalar @lines)
|
||||
{ last; };
|
||||
|
||||
$line = $lines[$lineIndex];
|
||||
};
|
||||
|
||||
if ($lineRemainder !~ /^[ \t]*$/)
|
||||
{
|
||||
# If there was something past the closing symbol this wasn't an acceptable comment.
|
||||
|
||||
if ($isMultiLine)
|
||||
{ $self->TokenizeLine($lineRemainder); }
|
||||
else
|
||||
{
|
||||
# We go back to the original line if it wasn't a multiline comment because we want the comment to stay in the
|
||||
# code. Otherwise the /*@out@*/ from the example would be removed.
|
||||
$self->TokenizeLine($lines[$lineIndex]);
|
||||
};
|
||||
|
||||
@commentLines = ( );
|
||||
}
|
||||
else
|
||||
{
|
||||
push @$tokens, "\n";
|
||||
};
|
||||
|
||||
$lineIndex++;
|
||||
}
|
||||
|
||||
|
||||
# Otherwise just add it to the code.
|
||||
|
||||
else
|
||||
{
|
||||
$self->TokenizeLine($line);
|
||||
$lineIndex++;
|
||||
};
|
||||
|
||||
|
||||
# If there were comments, send them to Parser->OnComment().
|
||||
|
||||
if (scalar @commentLines)
|
||||
{
|
||||
NaturalDocs::Parser->OnComment(\@commentLines, $commentLineNumber, $isJavaDoc);
|
||||
@commentLines = ( );
|
||||
$isJavaDoc = undef;
|
||||
};
|
||||
|
||||
# $lineIndex was incremented by the individual code paths above.
|
||||
|
||||
}; # while ($lineIndex < scalar @lines)
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PreprocessFile
|
||||
#
|
||||
# An overridable function if you'd like to preprocess the file before it goes into <ParseForCommentsAndTokens()>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lines - An arrayref to the file's lines. Each line has its line break stripped off, but is otherwise untouched.
|
||||
#
|
||||
sub PreprocessFile #(lines)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: TokenizeLine
|
||||
#
|
||||
# Converts the passed line to tokens as described in <ParseForCommentsAndTokens> and adds them to <Tokens()>. Also
|
||||
# adds a line break token after it.
|
||||
#
|
||||
sub TokenizeLine #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
push @{$self->Tokens()}, $line =~ /(\w+|[ \t]+|.)/g, "\n";
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: TryToSkipString
|
||||
#
|
||||
# If the position is on a string delimiter, moves the position to the token following the closing delimiter, or past the end of the
|
||||
# tokens if there is none. Assumes all other characters are allowed in the string, the delimiter itself is allowed if it's preceded by
|
||||
# a backslash, and line breaks are allowed in the string.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# indexRef - A reference to the position's index into <Tokens()>.
|
||||
# lineNumberRef - A reference to the position's line number.
|
||||
# openingDelimiter - The opening string delimiter, such as a quote or an apostrophe.
|
||||
# closingDelimiter - The closing string delimiter, if different. If not defined, assumes the same as openingDelimiter.
|
||||
# startContentIndexRef - A reference to a variable in which to store the index of the first token of the string's content.
|
||||
# May be undef.
|
||||
# endContentIndexRef - A reference to a variable in which to store the index of the end of the string's content, which is one
|
||||
# past the last index of content. May be undef.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the position was on the passed delimiter or not. The index, line number, and content index ref variables will be
|
||||
# updated only if true.
|
||||
#
|
||||
sub TryToSkipString #(indexRef, lineNumberRef, openingDelimiter, closingDelimiter, startContentIndexRef, endContentIndexRef)
|
||||
{
|
||||
my ($self, $index, $lineNumber, $openingDelimiter, $closingDelimiter, $startContentIndexRef, $endContentIndexRef) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
if (!defined $closingDelimiter)
|
||||
{ $closingDelimiter = $openingDelimiter; };
|
||||
|
||||
if ($tokens->[$$index] ne $openingDelimiter)
|
||||
{ return undef; };
|
||||
|
||||
|
||||
$$index++;
|
||||
if (defined $startContentIndexRef)
|
||||
{ $$startContentIndexRef = $$index; };
|
||||
|
||||
while ($$index < scalar @$tokens)
|
||||
{
|
||||
if ($tokens->[$$index] eq "\\")
|
||||
{
|
||||
# Skip the token after it.
|
||||
$$index += 2;
|
||||
}
|
||||
elsif ($tokens->[$$index] eq "\n")
|
||||
{
|
||||
$$lineNumber++;
|
||||
$$index++;
|
||||
}
|
||||
elsif ($tokens->[$$index] eq $closingDelimiter)
|
||||
{
|
||||
if (defined $endContentIndexRef)
|
||||
{ $$endContentIndexRef = $$index; };
|
||||
|
||||
$$index++;
|
||||
last;
|
||||
}
|
||||
else
|
||||
{
|
||||
$$index++;
|
||||
};
|
||||
};
|
||||
|
||||
if ($$index >= scalar @$tokens && defined $endContentIndexRef)
|
||||
{ $$endContentIndexRef = scalar @$tokens; };
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SkipRestOfLine
|
||||
#
|
||||
# Moves the position to the token following the next line break, or past the end of the tokens array if there is none. Useful for
|
||||
# line comments.
|
||||
#
|
||||
# Note that it skips blindly. It assumes there cannot be anything of interest, such as a string delimiter, between the position
|
||||
# and the end of the line.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# indexRef - A reference to the position's index into <Tokens()>.
|
||||
# lineNumberRef - A reference to the position's line number.
|
||||
|
||||
sub SkipRestOfLine #(indexRef, lineNumberRef)
|
||||
{
|
||||
my ($self, $index, $lineNumber) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
while ($$index < scalar @$tokens)
|
||||
{
|
||||
if ($tokens->[$$index] eq "\n")
|
||||
{
|
||||
$$lineNumber++;
|
||||
$$index++;
|
||||
last;
|
||||
}
|
||||
else
|
||||
{
|
||||
$$index++;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SkipUntilAfter
|
||||
#
|
||||
# Moves the position to the token following the next occurance of a particular token sequence, or past the end of the tokens
|
||||
# array if it never occurs. Useful for multiline comments.
|
||||
#
|
||||
# Note that it skips blindly. It assumes there cannot be anything of interest, such as a string delimiter, between the position
|
||||
# and the end of the line.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# indexRef - A reference to the position's index.
|
||||
# lineNumberRef - A reference to the position's line number.
|
||||
# token - A token that must be matched. Can be specified multiple times to match a sequence of tokens.
|
||||
#
|
||||
sub SkipUntilAfter #(indexRef, lineNumberRef, token, token, ...)
|
||||
{
|
||||
my ($self, $index, $lineNumber, @target) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
while ($$index < scalar @$tokens)
|
||||
{
|
||||
if ($tokens->[$$index] eq $target[0] && ($$index + scalar @target) <= scalar @$tokens)
|
||||
{
|
||||
my $match = 1;
|
||||
|
||||
for (my $i = 1; $i < scalar @target; $i++)
|
||||
{
|
||||
if ($tokens->[$$index+$i] ne $target[$i])
|
||||
{
|
||||
$match = 0;
|
||||
last;
|
||||
};
|
||||
};
|
||||
|
||||
if ($match)
|
||||
{
|
||||
$$index += scalar @target;
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
if ($tokens->[$$index] eq "\n")
|
||||
{
|
||||
$$lineNumber++;
|
||||
$$index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$$index++;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsFirstLineToken
|
||||
#
|
||||
# Returns whether the position is at the first token of a line, not including whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# index - The index of the position.
|
||||
#
|
||||
sub IsFirstLineToken #(index)
|
||||
{
|
||||
my ($self, $index) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
if ($index == 0)
|
||||
{ return 1; };
|
||||
|
||||
$index--;
|
||||
|
||||
if ($tokens->[$index] =~ /^[ \t]/)
|
||||
{ $index--; };
|
||||
|
||||
if ($index <= 0 || $tokens->[$index] eq "\n")
|
||||
{ return 1; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsLastLineToken
|
||||
#
|
||||
# Returns whether the position is at the last token of a line, not including whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# index - The index of the position.
|
||||
#
|
||||
sub IsLastLineToken #(index)
|
||||
{
|
||||
my ($self, $index) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
do
|
||||
{ $index++; }
|
||||
while ($index < scalar @$tokens && $tokens->[$index] =~ /^[ \t]/);
|
||||
|
||||
if ($index >= scalar @$tokens || $tokens->[$index] eq "\n")
|
||||
{ return 1; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsAtSequence
|
||||
#
|
||||
# Returns whether the position is at a sequence of tokens.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# index - The index of the position.
|
||||
# token - A token to match. Specify multiple times to specify the sequence.
|
||||
#
|
||||
sub IsAtSequence #(index, token, token, token ...)
|
||||
{
|
||||
my ($self, $index, @target) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
if ($index + scalar @target > scalar @$tokens)
|
||||
{ return undef; };
|
||||
|
||||
for (my $i = 0; $i < scalar @target; $i++)
|
||||
{
|
||||
if ($tokens->[$index + $i] ne $target[$i])
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsBackslashed
|
||||
#
|
||||
# Returns whether the position is after a backslash.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# index - The index of the postition.
|
||||
#
|
||||
sub IsBackslashed #(index)
|
||||
{
|
||||
my ($self, $index) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
if ($index > 0 && $tokens->[$index - 1] eq "\\")
|
||||
{ return 1; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Group: Scope Functions
|
||||
#
|
||||
# These functions provide a nice scope stack implementation for language-specific parsers to use. The default implementation
|
||||
# makes the following assumptions.
|
||||
#
|
||||
# - Packages completely replace one another, rather than concatenating. You need to concatenate manually if that's the
|
||||
# behavior.
|
||||
#
|
||||
# - Packages inherit, so if a scope level doesn't set its own, the package is the same as the parent scope's.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: ClearScopeStack
|
||||
#
|
||||
# Clears the scope stack for a new file. Not necessary if you call <ParseForCommentsAndTokens()>.
|
||||
#
|
||||
sub ClearScopeStack
|
||||
{
|
||||
my ($self) = @_;
|
||||
$self->[SCOPE_STACK] = [ NaturalDocs::Languages::Advanced::Scope->New(undef, undef) ];
|
||||
$self->[SCOPE_RECORD] = [ NaturalDocs::Languages::Advanced::ScopeChange->New(undef, 1) ];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: StartScope
|
||||
#
|
||||
# Records a new scope level.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# closingSymbol - The closing symbol of the scope.
|
||||
# lineNumber - The line number where the scope begins.
|
||||
# package - The package <SymbolString> of the scope. Undef means no change.
|
||||
#
|
||||
sub StartScope #(closingSymbol, lineNumber, package)
|
||||
{
|
||||
my ($self, $closingSymbol, $lineNumber, $package) = @_;
|
||||
|
||||
push @{$self->[SCOPE_STACK]},
|
||||
NaturalDocs::Languages::Advanced::Scope->New($closingSymbol, $package, $self->CurrentUsing());
|
||||
|
||||
$self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: EndScope
|
||||
#
|
||||
# Records the end of the current scope level. Note that this is blind; you need to manually check <ClosingScopeSymbol()> if
|
||||
# you need to determine if it is correct to do so.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineNumber - The line number where the scope ends.
|
||||
#
|
||||
sub EndScope #(lineNumber)
|
||||
{
|
||||
my ($self, $lineNumber) = @_;
|
||||
|
||||
if (scalar @{$self->[SCOPE_STACK]} > 1)
|
||||
{ pop @{$self->[SCOPE_STACK]}; };
|
||||
|
||||
$self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ClosingScopeSymbol
|
||||
#
|
||||
# Returns the symbol that ends the current scope level, or undef if we are at the top level.
|
||||
#
|
||||
sub ClosingScopeSymbol
|
||||
{
|
||||
my ($self) = @_;
|
||||
return $self->[SCOPE_STACK]->[-1]->ClosingSymbol();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CurrentScope
|
||||
#
|
||||
# Returns the current calculated scope, or undef if global. The default implementation just returns <CurrentPackage()>. This
|
||||
# is a separate function because C++ may need to track namespaces and classes separately, and so the current scope would
|
||||
# be a concatenation of them.
|
||||
#
|
||||
sub CurrentScope
|
||||
{
|
||||
return $_[0]->CurrentPackage();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CurrentPackage
|
||||
#
|
||||
# Returns the current calculated package or class, or undef if none.
|
||||
#
|
||||
sub CurrentPackage
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $package;
|
||||
|
||||
for (my $index = scalar @{$self->[SCOPE_STACK]} - 1; $index >= 0 && !defined $package; $index--)
|
||||
{
|
||||
$package = $self->[SCOPE_STACK]->[$index]->Package();
|
||||
};
|
||||
|
||||
return $package;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetPackage
|
||||
#
|
||||
# Sets the package for the current scope level.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# package - The new package <SymbolString>.
|
||||
# lineNumber - The line number the new package starts on.
|
||||
#
|
||||
sub SetPackage #(package, lineNumber)
|
||||
{
|
||||
my ($self, $package, $lineNumber) = @_;
|
||||
$self->[SCOPE_STACK]->[-1]->SetPackage($package);
|
||||
|
||||
$self->AddToScopeRecord($self->CurrentScope(), $lineNumber);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CurrentUsing
|
||||
#
|
||||
# Returns the current calculated arrayref of <SymbolStrings> from Using statements, or undef if none.
|
||||
#
|
||||
sub CurrentUsing
|
||||
{
|
||||
my ($self) = @_;
|
||||
return $self->[SCOPE_STACK]->[-1]->Using();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddUsing
|
||||
#
|
||||
# Adds a Using <SymbolString> to the current scope.
|
||||
#
|
||||
sub AddUsing #(using)
|
||||
{
|
||||
my ($self, $using) = @_;
|
||||
$self->[SCOPE_STACK]->[-1]->AddUsing($using);
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: AddToScopeRecord
|
||||
#
|
||||
# Adds a change to the scope record, condensing unnecessary entries.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# newScope - What the scope <SymbolString> changed to.
|
||||
# lineNumber - Where the scope changed.
|
||||
#
|
||||
sub AddToScopeRecord #(newScope, lineNumber)
|
||||
{
|
||||
my ($self, $scope, $lineNumber) = @_;
|
||||
my $scopeRecord = $self->ScopeRecord();
|
||||
|
||||
if ($scope ne $scopeRecord->[-1]->Scope())
|
||||
{
|
||||
if ($scopeRecord->[-1]->LineNumber() == $lineNumber)
|
||||
{ $scopeRecord->[-1]->SetScope($scope); }
|
||||
else
|
||||
{ push @$scopeRecord, NaturalDocs::Languages::Advanced::ScopeChange->New($scope, $lineNumber); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CreateString
|
||||
#
|
||||
# Converts the specified tokens into a string and returns it.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# startIndex - The starting index to convert.
|
||||
# endIndex - The ending index, which is *not inclusive*.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The string.
|
||||
#
|
||||
sub CreateString #(startIndex, endIndex)
|
||||
{
|
||||
my ($self, $startIndex, $endIndex) = @_;
|
||||
my $tokens = $self->Tokens();
|
||||
|
||||
my $string;
|
||||
|
||||
while ($startIndex < $endIndex && $startIndex < scalar @$tokens)
|
||||
{
|
||||
$string .= $tokens->[$startIndex];
|
||||
$startIndex++;
|
||||
};
|
||||
|
||||
return $string;
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,96 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Advanced::Scope
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class used to store a scope level.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Advanced::Scope;
|
||||
|
||||
#
|
||||
# Constants: Implementation
|
||||
#
|
||||
# The object is implemented as a blessed arrayref. The constants below are used as indexes.
|
||||
#
|
||||
# CLOSING_SYMBOL - The closing symbol character of the scope.
|
||||
# PACKAGE - The package <SymbolString> of the scope.
|
||||
# USING - An arrayref of <SymbolStrings> for using statements, or undef if none.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'CLOSING_SYMBOL', 'PACKAGE', 'USING';
|
||||
# Dependency: New() depends on the order of these constants as well as that there is no inherited members.
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# closingSymbol - The closing symbol character of the scope.
|
||||
# package - The package <SymbolString> of the scope.
|
||||
# using - An arrayref of using <SymbolStrings>, or undef if none. The contents of the array will be duplicated.
|
||||
#
|
||||
# If package is set to undef, it is assumed that it inherits the value of the previous scope on the stack.
|
||||
#
|
||||
sub New #(closingSymbol, package, using)
|
||||
{
|
||||
# Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited
|
||||
# members.
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
if (defined $object->[USING])
|
||||
{ $object->[USING] = [ @{$object->[USING]} ]; };
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: ClosingSymbol
|
||||
# Returns the closing symbol character of the scope.
|
||||
sub ClosingSymbol
|
||||
{ return $_[0]->[CLOSING_SYMBOL]; };
|
||||
|
||||
# Function: Package
|
||||
# Returns the package <SymbolString> of the scope, or undef if none.
|
||||
sub Package
|
||||
{ return $_[0]->[PACKAGE]; };
|
||||
|
||||
# Function: SetPackage
|
||||
# Sets the package <SymbolString> of the scope.
|
||||
sub SetPackage #(package)
|
||||
{ $_[0]->[PACKAGE] = $_[1]; };
|
||||
|
||||
# Function: Using
|
||||
# Returns an arrayref of <SymbolStrings> for using statements, or undef if none
|
||||
sub Using
|
||||
{ return $_[0]->[USING]; };
|
||||
|
||||
# Function: AddUsing
|
||||
# Adds a <SymbolString> to the <Using()> array.
|
||||
sub AddUsing #(using)
|
||||
{
|
||||
my ($self, $using) = @_;
|
||||
|
||||
if (!defined $self->[USING])
|
||||
{ $self->[USING] = [ ]; };
|
||||
|
||||
push @{$self->[USING]}, $using;
|
||||
};
|
||||
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,71 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Advanced::ScopeChange
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class used to store a scope change.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Advanced::ScopeChange;
|
||||
|
||||
#
|
||||
# Constants: Implementation
|
||||
#
|
||||
# The object is implemented as a blessed arrayref. The constants below are used as indexes.
|
||||
#
|
||||
# SCOPE - The new scope <SymbolString>.
|
||||
# LINE_NUMBER - The line number of the change.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'SCOPE', 'LINE_NUMBER';
|
||||
# Dependency: New() depends on the order of these constants as well as that there is no inherited members.
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# scope - The <SymbolString> the scope was changed to.
|
||||
# lineNumber - What line it occurred on.
|
||||
#
|
||||
sub New #(scope, lineNumber)
|
||||
{
|
||||
# Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited
|
||||
# members.
|
||||
my $self = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $self;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Scope
|
||||
# Returns the <SymbolString> the scope was changed to.
|
||||
sub Scope
|
||||
{ return $_[0]->[SCOPE]; };
|
||||
|
||||
# Function: SetScope
|
||||
# Replaces the <SymbolString> the scope was changed to.
|
||||
sub SetScope #(scope)
|
||||
{ $_[0]->[SCOPE] = $_[1]; };
|
||||
|
||||
# Function: LineNumber
|
||||
# Returns the line number of the change.
|
||||
sub LineNumber
|
||||
{ return $_[0]->[LINE_NUMBER]; };
|
||||
|
||||
|
||||
1;
|
833
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Base.pm
Executable file
833
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Base.pm
Executable file
@ -0,0 +1,833 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Base
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A base class for all programming language parsers.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Base;
|
||||
|
||||
use NaturalDocs::DefineMembers 'NAME', 'Name()',
|
||||
'EXTENSIONS', 'Extensions()', 'SetExtensions() duparrayref',
|
||||
'SHEBANG_STRINGS', 'ShebangStrings()', 'SetShebangStrings() duparrayref',
|
||||
'IGNORED_PREFIXES',
|
||||
'ENUM_VALUES';
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ('ENUM_GLOBAL', 'ENUM_UNDER_TYPE', 'ENUM_UNDER_PARENT');
|
||||
|
||||
|
||||
#
|
||||
# Constants: EnumValuesType
|
||||
#
|
||||
# How enum values are handled in the language.
|
||||
#
|
||||
# ENUM_GLOBAL - Values are always global and thus 'value'.
|
||||
# ENUM_UNDER_TYPE - Values are under the type in the hierarchy, and thus 'package.enum.value'.
|
||||
# ENUM_UNDER_PARENT - Values are under the parent in the hierarchy, putting them on the same level as the enum itself. Thus
|
||||
# 'package.value'.
|
||||
#
|
||||
use constant ENUM_GLOBAL => 1;
|
||||
use constant ENUM_UNDER_TYPE => 2;
|
||||
use constant ENUM_UNDER_PARENT => 3;
|
||||
|
||||
|
||||
#
|
||||
# Handle: SOURCEFILEHANDLE
|
||||
#
|
||||
# The handle of the source file currently being parsed.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# name - The name of the language.
|
||||
#
|
||||
sub New #(name)
|
||||
{
|
||||
my ($selfPackage, $name) = @_;
|
||||
|
||||
my $object = [ ];
|
||||
|
||||
$object->[NAME] = $name;
|
||||
|
||||
bless $object, $selfPackage;
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Members
|
||||
#
|
||||
# Name - Returns the language's name.
|
||||
# Extensions - Returns an arrayref of the language's file extensions, or undef if none.
|
||||
# SetExtensions - Replaces the arrayref of the language's file extensions.
|
||||
# ShebangStrings - Returns an arrayref of the language's shebang strings, or undef if none.
|
||||
# SetShebangStrings - Replaces the arrayref of the language's shebang strings.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: PackageSeparator
|
||||
# Returns the language's package separator string.
|
||||
#
|
||||
sub PackageSeparator
|
||||
{ return '.'; };
|
||||
|
||||
#
|
||||
# Function: PackageSeparatorWasSet
|
||||
# Returns whether the language's package separator string was ever changed from the default.
|
||||
#
|
||||
sub PackageSeparatorWasSet
|
||||
{ return 0; };
|
||||
|
||||
|
||||
#
|
||||
# Function: EnumValues
|
||||
# Returns the <EnumValuesType> that describes how the language handles enums.
|
||||
#
|
||||
sub EnumValues
|
||||
{ return ENUM_GLOBAL; };
|
||||
|
||||
|
||||
#
|
||||
# Function: IgnoredPrefixesFor
|
||||
#
|
||||
# Returns an arrayref of ignored prefixes for the passed <TopicType>, or undef if none. The array is sorted so that the longest
|
||||
# prefixes are first.
|
||||
#
|
||||
sub IgnoredPrefixesFor #(type)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
if (defined $self->[IGNORED_PREFIXES])
|
||||
{ return $self->[IGNORED_PREFIXES]->{$type}; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetIgnoredPrefixesFor
|
||||
#
|
||||
# Replaces the arrayref of ignored prefixes for the passed <TopicType>.
|
||||
#
|
||||
sub SetIgnoredPrefixesFor #(type, prefixes)
|
||||
{
|
||||
my ($self, $type, $prefixesRef) = @_;
|
||||
|
||||
if (!defined $self->[IGNORED_PREFIXES])
|
||||
{ $self->[IGNORED_PREFIXES] = { }; };
|
||||
|
||||
if (!defined $prefixesRef)
|
||||
{ delete $self->[IGNORED_PREFIXES]->{$type}; }
|
||||
else
|
||||
{
|
||||
my $prefixes = [ @$prefixesRef ];
|
||||
|
||||
# Sort prefixes to be longest to shortest.
|
||||
@$prefixes = sort { length $b <=> length $a } @$prefixes;
|
||||
|
||||
$self->[IGNORED_PREFIXES]->{$type} = $prefixes;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasIgnoredPrefixes
|
||||
#
|
||||
# Returns whether the language has any ignored prefixes at all.
|
||||
#
|
||||
sub HasIgnoredPrefixes
|
||||
{ return defined $_[0]->[IGNORED_PREFIXES]; };
|
||||
|
||||
|
||||
#
|
||||
# Function: CopyIgnoredPrefixesOf
|
||||
#
|
||||
# Copies all the ignored prefix settings of the passed <NaturalDocs::Languages::Base> object.
|
||||
#
|
||||
sub CopyIgnoredPrefixesOf #(language)
|
||||
{
|
||||
my ($self, $language) = @_;
|
||||
|
||||
if ($language->HasIgnoredPrefixes())
|
||||
{
|
||||
$self->[IGNORED_PREFIXES] = { };
|
||||
|
||||
while (my ($topicType, $prefixes) = each %{$language->[IGNORED_PREFIXES]})
|
||||
{
|
||||
$self->[IGNORED_PREFIXES]->{$topicType} = [ @$prefixes ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Parsing Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseFile
|
||||
#
|
||||
# Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
|
||||
# This *must* be defined by a subclass.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The <FileName> of the source file to parse.
|
||||
# topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The array ( autoTopics, scopeRecord ).
|
||||
#
|
||||
# autoTopics - An arrayref of automatically generated <NaturalDocs::Parser::ParsedTopics> from the file, or undef if none.
|
||||
# scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: ParsePrototype
|
||||
#
|
||||
# Parses the prototype and returns it as a <NaturalDocs::Languages::Prototype> object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType>.
|
||||
# prototype - The text prototype.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# A <NaturalDocs::Languages::Prototype> object.
|
||||
#
|
||||
sub ParsePrototype #(type, prototype)
|
||||
{
|
||||
my ($self, $type, $prototype) = @_;
|
||||
|
||||
my $isClass = NaturalDocs::Topics->TypeInfo($type)->ClassHierarchy();
|
||||
|
||||
if ($prototype !~ /\(.*[^ ].*\)/ && (!$isClass || $prototype !~ /\{.*[^ ].*\}/))
|
||||
{
|
||||
my $object = NaturalDocs::Languages::Prototype->New($prototype);
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Parse the parameters out of the prototype.
|
||||
|
||||
my @tokens = $prototype =~ /([^\(\)\[\]\{\}\<\>\'\"\,\;]+|.)/g;
|
||||
|
||||
my $parameter;
|
||||
my @parameterLines;
|
||||
|
||||
my @symbolStack;
|
||||
my $finishedParameters;
|
||||
|
||||
my ($beforeParameters, $afterParameters);
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($finishedParameters)
|
||||
{ $afterParameters .= $token; }
|
||||
|
||||
elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
|
||||
{
|
||||
if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
|
||||
if ($token eq $symbolStack[-1])
|
||||
{ pop @symbolStack; };
|
||||
}
|
||||
|
||||
elsif ($token =~ /^[\(\[\{\<\'\"]$/)
|
||||
{
|
||||
if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
|
||||
push @symbolStack, $token;
|
||||
}
|
||||
|
||||
elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
|
||||
($token eq ']' && $symbolStack[-1] eq '[') ||
|
||||
($token eq '}' && $symbolStack[-1] eq '{') ||
|
||||
($token eq '>' && $symbolStack[-1] eq '<') )
|
||||
{
|
||||
if ($symbolStack[0] eq '(')
|
||||
{
|
||||
if ($token eq ')' && scalar @symbolStack == 1)
|
||||
{
|
||||
if ($parameter ne ' ')
|
||||
{ push @parameterLines, $parameter; };
|
||||
|
||||
$finishedParameters = 1;
|
||||
$afterParameters .= $token;
|
||||
}
|
||||
else
|
||||
{ $parameter .= $token; };
|
||||
}
|
||||
elsif ($isClass && $symbolStack[0] eq '{')
|
||||
{
|
||||
if ($token eq '}' && scalar @symbolStack == 1)
|
||||
{
|
||||
if ($parameter ne ' ')
|
||||
{ push @parameterLines, $parameter; };
|
||||
|
||||
$finishedParameters = 1;
|
||||
$afterParameters .= $token;
|
||||
}
|
||||
else
|
||||
{ $parameter .= $token; };
|
||||
}
|
||||
else
|
||||
{
|
||||
$beforeParameters .= $token;
|
||||
};
|
||||
|
||||
pop @symbolStack;
|
||||
}
|
||||
|
||||
elsif ($token eq ',' || $token eq ';')
|
||||
{
|
||||
if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
|
||||
{
|
||||
if (scalar @symbolStack == 1)
|
||||
{
|
||||
push @parameterLines, $parameter . $token;
|
||||
$parameter = undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parameter .= $token;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
$beforeParameters .= $token;
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ($symbolStack[0] eq '(' || ($isClass && $symbolStack[0] eq '{'))
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
};
|
||||
};
|
||||
|
||||
foreach my $part (\$beforeParameters, \$afterParameters)
|
||||
{
|
||||
$$part =~ s/^ //;
|
||||
$$part =~ s/ $//;
|
||||
};
|
||||
|
||||
my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
|
||||
|
||||
|
||||
# Parse the actual parameters.
|
||||
|
||||
foreach my $parameterLine (@parameterLines)
|
||||
{
|
||||
$prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
|
||||
};
|
||||
|
||||
return $prototypeObject;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseParameterLine
|
||||
#
|
||||
# Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
|
||||
#
|
||||
# This vesion assumes a C++ style line. If you need a Pascal style line, override this function to forward to
|
||||
# <ParsePascalParameterLine()>.
|
||||
#
|
||||
# > Function(parameter, type parameter, type parameter = value);
|
||||
#
|
||||
sub ParseParameterLine #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
|
||||
$line =~ s/^ //;
|
||||
$line =~ s/ $//;
|
||||
|
||||
my @tokens = $line =~ /([^ \(\)\{\}\[\]\<\>\'\"\=]+|.)/g;
|
||||
|
||||
my @symbolStack;
|
||||
my @parameterWords = ( undef );
|
||||
my ($defaultValue, $defaultValuePrefix, $inDefaultValue);
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($inDefaultValue)
|
||||
{ $defaultValue .= $token; }
|
||||
|
||||
elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
|
||||
{
|
||||
$parameterWords[-1] .= $token;
|
||||
|
||||
if ($token eq $symbolStack[-1])
|
||||
{ pop @symbolStack; };
|
||||
}
|
||||
|
||||
elsif ($token =~ /^[\(\[\{\<\'\"]$/)
|
||||
{
|
||||
push @symbolStack, $token;
|
||||
$parameterWords[-1] .= $token;
|
||||
}
|
||||
|
||||
elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
|
||||
($token eq ']' && $symbolStack[-1] eq '[') ||
|
||||
($token eq '}' && $symbolStack[-1] eq '{') ||
|
||||
($token eq '>' && $symbolStack[-1] eq '<') )
|
||||
{
|
||||
pop @symbolStack;
|
||||
$parameterWords[-1] .= $token;
|
||||
}
|
||||
|
||||
elsif ($token eq ' ')
|
||||
{
|
||||
if (!scalar @symbolStack)
|
||||
{ push @parameterWords, undef; }
|
||||
else
|
||||
{ $parameterWords[-1] .= $token; };
|
||||
}
|
||||
|
||||
elsif ($token eq '=')
|
||||
{
|
||||
if (!scalar @symbolStack)
|
||||
{
|
||||
$defaultValuePrefix = $token;
|
||||
$inDefaultValue = 1;
|
||||
}
|
||||
else
|
||||
{ $parameterWords[-1] .= $token; };
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$parameterWords[-1] .= $token;
|
||||
};
|
||||
};
|
||||
|
||||
my ($name, $namePrefix, $type, $typePrefix);
|
||||
|
||||
if (!$parameterWords[-1])
|
||||
{ pop @parameterWords; };
|
||||
|
||||
$name = pop @parameterWords;
|
||||
|
||||
if ($parameterWords[-1]=~ /([\*\&]+)$/)
|
||||
{
|
||||
$namePrefix = $1;
|
||||
$parameterWords[-1] = substr($parameterWords[-1], 0, 0 - length($namePrefix));
|
||||
$parameterWords[-1] =~ s/ $//;
|
||||
|
||||
if (!$parameterWords[-1])
|
||||
{ pop @parameterWords; };
|
||||
}
|
||||
elsif ($name =~ /^([\*\&]+)/)
|
||||
{
|
||||
$namePrefix = $1;
|
||||
$name = substr($name, length($namePrefix));
|
||||
$name =~ s/^ //;
|
||||
};
|
||||
|
||||
$type = pop @parameterWords;
|
||||
$typePrefix = join(' ', @parameterWords);
|
||||
|
||||
if ($typePrefix)
|
||||
{ $typePrefix .= ' '; };
|
||||
|
||||
if ($type =~ /^([a-z0-9_\:\.]+(?:\.|\:\:))[a-z0-9_]/i)
|
||||
{
|
||||
my $attachedTypePrefix = $1;
|
||||
|
||||
$typePrefix .= $attachedTypePrefix;
|
||||
$type = substr($type, length($attachedTypePrefix));
|
||||
};
|
||||
|
||||
$defaultValue =~ s/ $//;
|
||||
|
||||
return NaturalDocs::Languages::Prototype::Parameter->New($type, $typePrefix, $name, $namePrefix,
|
||||
$defaultValue, $defaultValuePrefix);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParsePascalParameterLine
|
||||
#
|
||||
# Parses a Pascal-like prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
|
||||
# Pascal lines are as follows:
|
||||
#
|
||||
# > Function (name: type; name, name: type := value)
|
||||
#
|
||||
# Also supports ActionScript lines
|
||||
#
|
||||
# > Function (name: type, name, name: type = value)
|
||||
#
|
||||
sub ParsePascalParameterLine #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
|
||||
$line =~ s/^ //;
|
||||
$line =~ s/ $//;
|
||||
|
||||
my @tokens = $line =~ /([^\(\)\{\}\[\]\<\>\'\"\=\:]+|\:\=|.)/g;
|
||||
my ($type, $name, $defaultValue, $defaultValuePrefix, $afterName, $afterDefaultValue);
|
||||
my @symbolStack;
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($afterDefaultValue)
|
||||
{ $defaultValue .= $token; }
|
||||
|
||||
elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
|
||||
{
|
||||
if ($afterName)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
|
||||
if ($token eq $symbolStack[-1])
|
||||
{ pop @symbolStack; };
|
||||
}
|
||||
|
||||
elsif ($token =~ /^[\(\[\{\<\'\"]$/)
|
||||
{
|
||||
push @symbolStack, $token;
|
||||
|
||||
if ($afterName)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
}
|
||||
|
||||
elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
|
||||
($token eq ']' && $symbolStack[-1] eq '[') ||
|
||||
($token eq '}' && $symbolStack[-1] eq '{') ||
|
||||
($token eq '>' && $symbolStack[-1] eq '<') )
|
||||
{
|
||||
pop @symbolStack;
|
||||
|
||||
if ($afterName)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
}
|
||||
|
||||
elsif ($afterName)
|
||||
{
|
||||
if (($token eq ':=' || $token eq '=') && !scalar @symbolStack)
|
||||
{
|
||||
$defaultValuePrefix = $token;
|
||||
$afterDefaultValue = 1;
|
||||
}
|
||||
else
|
||||
{ $type .= $token; };
|
||||
}
|
||||
|
||||
elsif ($token eq ':' && !scalar @symbolStack)
|
||||
{
|
||||
$name .= $token;
|
||||
$afterName = 1;
|
||||
}
|
||||
|
||||
else
|
||||
{ $name .= $token; };
|
||||
};
|
||||
|
||||
foreach my $part (\$type, \$name, \$defaultValue)
|
||||
{
|
||||
$$part =~ s/^ //;
|
||||
$$part =~ s/ $//;
|
||||
};
|
||||
|
||||
return NaturalDocs::Languages::Prototype::Parameter->New($type, undef, $name, undef, $defaultValue, $defaultValuePrefix);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: TypeBeforeParameter
|
||||
#
|
||||
# Returns whether the type appears before the parameter in prototypes.
|
||||
#
|
||||
# For example, it does in C++
|
||||
# > void Function (int a, int b)
|
||||
#
|
||||
# but does not in Pascal
|
||||
# > function Function (a: int; b, c: int)
|
||||
#
|
||||
sub TypeBeforeParameter
|
||||
{
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Function: IgnoredPrefixLength
|
||||
#
|
||||
# Returns the length of the prefix that should be ignored in the index, or zero if none.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# name - The name of the symbol.
|
||||
# type - The symbol's <TopicType>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The length of the prefix to ignore, or zero if none.
|
||||
#
|
||||
sub IgnoredPrefixLength #(name, type)
|
||||
{
|
||||
my ($self, $name, $type) = @_;
|
||||
|
||||
foreach my $prefixes ($self->IgnoredPrefixesFor($type), $self->IgnoredPrefixesFor(::TOPIC_GENERAL()))
|
||||
{
|
||||
if (defined $prefixes)
|
||||
{
|
||||
foreach my $prefix (@$prefixes)
|
||||
{
|
||||
if (substr($name, 0, length($prefix)) eq $prefix)
|
||||
{ return length($prefix); };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: StripOpeningSymbols
|
||||
#
|
||||
# Determines if the line starts with any of the passed symbols, and if so, replaces it with spaces. This only happens
|
||||
# if the only thing before it on the line is whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A reference to the line to check.
|
||||
# symbols - An arrayref of the symbols to check for.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the line starts with any of the passed comment symbols, it will replace it in the line with spaces and return the symbol.
|
||||
# If the line doesn't, it will leave the line alone and return undef.
|
||||
#
|
||||
sub StripOpeningSymbols #(lineRef, symbols)
|
||||
{
|
||||
my ($self, $lineRef, $symbols) = @_;
|
||||
|
||||
if (!defined $symbols)
|
||||
{ return undef; };
|
||||
|
||||
my ($index, $symbol) = ::FindFirstSymbol($$lineRef, $symbols);
|
||||
|
||||
if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/)
|
||||
{
|
||||
return substr($$lineRef, $index, length($symbol), ' ' x length($symbol));
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: StripOpeningJavaDocSymbols
|
||||
#
|
||||
# Determines if the line starts with any of the passed symbols, and if so, replaces it with spaces. This only happens
|
||||
# if the only thing before it on the line is whitespace and the next character after it is whitespace or the end of the line.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A reference to the line to check.
|
||||
# symbols - An arrayref of the symbols to check for.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the line starts with any of the passed comment symbols, it will replace it in the line with spaces and return the symbol.
|
||||
# If the line doesn't, it will leave the line alone and return undef.
|
||||
#
|
||||
sub StripOpeningJavaDocSymbols #(lineRef, symbols)
|
||||
{
|
||||
my ($self, $lineRef, $symbols) = @_;
|
||||
|
||||
if (!defined $symbols)
|
||||
{ return undef; };
|
||||
|
||||
my ($index, $symbol) = ::FindFirstSymbol($$lineRef, $symbols);
|
||||
|
||||
if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/ && substr($$lineRef, $index + length($symbol), 1) =~ /^[ \t]?$/)
|
||||
{
|
||||
return substr($$lineRef, $index, length($symbol), ' ' x length($symbol));
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: StripOpeningBlockSymbols
|
||||
#
|
||||
# Determines if the line starts with any of the opening symbols in the passed symbol pairs, and if so, replaces it with spaces.
|
||||
# This only happens if the only thing before it on the line is whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A reference to the line to check.
|
||||
# symbolPairs - An arrayref of the symbol pairs to check for. Pairs are specified as two consecutive array entries, with the
|
||||
# opening symbol first.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the line starts with any of the opening symbols, it will replace it in the line with spaces and return the closing symbol.
|
||||
# If the line doesn't, it will leave the line alone and return undef.
|
||||
#
|
||||
sub StripOpeningBlockSymbols #(lineRef, symbolPairs)
|
||||
{
|
||||
my ($self, $lineRef, $symbolPairs) = @_;
|
||||
|
||||
if (!defined $symbolPairs)
|
||||
{ return undef; };
|
||||
|
||||
for (my $i = 0; $i < scalar @$symbolPairs; $i += 2)
|
||||
{
|
||||
my $index = index($$lineRef, $symbolPairs->[$i]);
|
||||
|
||||
if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/)
|
||||
{
|
||||
substr($$lineRef, $index, length($symbolPairs->[$i]), ' ' x length($symbolPairs->[$i]));
|
||||
return $symbolPairs->[$i + 1];
|
||||
};
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: StripOpeningJavaDocBlockSymbols
|
||||
#
|
||||
# Determines if the line starts with any of the opening symbols in the passed symbol pairs, and if so, replaces it with spaces.
|
||||
# This only happens if the only thing before it on the line is whitespace and the next character is whitespace or the end of the line.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A reference to the line to check.
|
||||
# symbolPairs - An arrayref of the symbol pairs to check for. Pairs are specified as two consecutive array entries, with the
|
||||
# opening symbol first.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# If the line starts with any of the opening symbols, it will replace it in the line with spaces and return the closing symbol.
|
||||
# If the line doesn't, it will leave the line alone and return undef.
|
||||
#
|
||||
sub StripOpeningJavaDocBlockSymbols #(lineRef, symbolPairs)
|
||||
{
|
||||
my ($self, $lineRef, $symbolPairs) = @_;
|
||||
|
||||
if (!defined $symbolPairs)
|
||||
{ return undef; };
|
||||
|
||||
for (my $i = 0; $i < scalar @$symbolPairs; $i += 2)
|
||||
{
|
||||
my $index = index($$lineRef, $symbolPairs->[$i]);
|
||||
|
||||
if ($index != -1 && substr($$lineRef, 0, $index) =~ /^[ \t]*$/ &&
|
||||
substr($$lineRef, $index + length($symbolPairs->[$i]), 1) =~ /^[ \t]?$/)
|
||||
{
|
||||
substr($$lineRef, $index, length($symbolPairs->[$i]), ' ' x length($symbolPairs->[$i]));
|
||||
return $symbolPairs->[$i + 1];
|
||||
};
|
||||
};
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: StripClosingSymbol
|
||||
#
|
||||
# Determines if the line contains a symbol, and if so, truncates it just before the symbol.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A reference to the line to check.
|
||||
# symbol - The symbol to check for.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The remainder of the line, or undef if the symbol was not found.
|
||||
#
|
||||
sub StripClosingSymbol #(lineRef, symbol)
|
||||
{
|
||||
my ($self, $lineRef, $symbol) = @_;
|
||||
|
||||
my $index = index($$lineRef, $symbol);
|
||||
|
||||
if ($index != -1)
|
||||
{
|
||||
my $lineRemainder = substr($$lineRef, $index + length($symbol));
|
||||
$$lineRef = substr($$lineRef, 0, $index);
|
||||
|
||||
return $lineRemainder;
|
||||
}
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: NormalizePrototype
|
||||
#
|
||||
# Normalizes a prototype. Specifically, condenses spaces, tabs, and line breaks into single spaces and removes leading and
|
||||
# trailing ones.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# prototype - The original prototype string.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The normalized prototype.
|
||||
#
|
||||
sub NormalizePrototype #(prototype)
|
||||
{
|
||||
my ($self, $prototype) = @_;
|
||||
|
||||
$prototype =~ tr/ \t\r\n/ /s;
|
||||
$prototype =~ s/^ //;
|
||||
$prototype =~ s/ $//;
|
||||
|
||||
return $prototype;
|
||||
};
|
||||
|
||||
|
||||
1;
|
1552
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/CSharp.pm
Executable file
1552
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/CSharp.pm
Executable file
File diff suppressed because it is too large
Load Diff
320
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/PLSQL.pm
Executable file
320
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/PLSQL.pm
Executable file
@ -0,0 +1,320 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::PLSQL
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A subclass to handle the language variations of PL/SQL.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::PLSQL;
|
||||
|
||||
use base 'NaturalDocs::Languages::Simple';
|
||||
|
||||
|
||||
#
|
||||
# Function: OnPrototypeEnd
|
||||
#
|
||||
# Microsoft's SQL specifies parameters as shown below.
|
||||
#
|
||||
# > CREATE PROCEDURE Test @as int, @foo int AS ...
|
||||
#
|
||||
# Having a parameter @is or @as is perfectly valid even though those words are also used to end the prototype. We need to
|
||||
# ignore text-based enders preceded by an at sign. Also note that it does not have parenthesis for parameter lists. We need to
|
||||
# skip all commas if the prototype doesn't have parenthesis but does have @ characters.
|
||||
#
|
||||
# Identifiers such as function names may contain the characters $, #, and _, so if "as" or "is" appears directly after one of them
|
||||
# we need to ignore the ender there as well.
|
||||
#
|
||||
# > FUNCTION Something_is_something ...
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> of the prototype.
|
||||
# prototypeRef - A reference to the prototype so far, minus the ender in dispute.
|
||||
# ender - The ender symbol.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# ENDER_ACCEPT - The ender is accepted and the prototype is finished.
|
||||
# ENDER_IGNORE - The ender is rejected and parsing should continue. Note that the prototype will be rejected as a whole
|
||||
# if all enders are ignored before reaching the end of the code.
|
||||
# ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is. However, the prototype might
|
||||
# also continue on so continue parsing. If there is no accepted ender between here and
|
||||
# the end of the code this version will be accepted instead.
|
||||
# ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed. Use the last accepted
|
||||
# version and end parsing.
|
||||
#
|
||||
sub OnPrototypeEnd #(type, prototypeRef, ender)
|
||||
{
|
||||
my ($self, $type, $prototypeRef, $ender) = @_;
|
||||
|
||||
# _ should be handled already.
|
||||
if ($ender =~ /^[a-z]+$/i && substr($$prototypeRef, -1) =~ /^[\@\$\#]$/)
|
||||
{ return ::ENDER_IGNORE(); }
|
||||
|
||||
elsif ($type eq ::TOPIC_FUNCTION() && $ender eq ',')
|
||||
{
|
||||
if ($$prototypeRef =~ /^[^\(]*\@/)
|
||||
{ return ::ENDER_IGNORE(); }
|
||||
else
|
||||
{ return ::ENDER_ACCEPT(); };
|
||||
}
|
||||
|
||||
else
|
||||
{ return ::ENDER_ACCEPT(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParsePrototype
|
||||
#
|
||||
# Overridden to handle Microsoft's parenthesisless version. Otherwise just throws to the parent.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType>.
|
||||
# prototype - The text prototype.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# A <NaturalDocs::Languages::Prototype> object.
|
||||
#
|
||||
sub ParsePrototype #(type, prototype)
|
||||
{
|
||||
my ($self, $type, $prototype) = @_;
|
||||
|
||||
my $noParenthesisParameters = ($type eq ::TOPIC_FUNCTION() && $prototype =~ /^[^\(]*\@/);
|
||||
|
||||
if ($prototype !~ /\(.*[^ ].*\)/ && !$noParenthesisParameters)
|
||||
{ return $self->SUPER::ParsePrototype($type, $prototype); };
|
||||
|
||||
|
||||
|
||||
my ($beforeParameters, $afterParameters, $isAfterParameters);
|
||||
|
||||
if ($noParenthesisParameters)
|
||||
{
|
||||
($beforeParameters, $prototype) = split(/\@/, $prototype, 2);
|
||||
$prototype = '@' . $prototype;
|
||||
};
|
||||
|
||||
my @tokens = $prototype =~ /([^\(\)\[\]\{\}\<\>\'\"\,]+|.)/g;
|
||||
|
||||
my $parameter;
|
||||
my @parameterLines;
|
||||
|
||||
my @symbolStack;
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($isAfterParameters)
|
||||
{ $afterParameters .= $token; }
|
||||
|
||||
elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
|
||||
{
|
||||
if ($noParenthesisParameters || $symbolStack[0] eq '(')
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
|
||||
if ($token eq $symbolStack[-1])
|
||||
{ pop @symbolStack; };
|
||||
}
|
||||
|
||||
elsif ($token =~ /^[\(\[\{\<\'\"]$/)
|
||||
{
|
||||
if ($noParenthesisParameters || $symbolStack[0] eq '(')
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
|
||||
push @symbolStack, $token;
|
||||
}
|
||||
|
||||
elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
|
||||
($token eq ']' && $symbolStack[-1] eq '[') ||
|
||||
($token eq '}' && $symbolStack[-1] eq '{') ||
|
||||
($token eq '>' && $symbolStack[-1] eq '<') )
|
||||
{
|
||||
if (!$noParenthesisParameters && $token eq ')' && scalar @symbolStack == 1 && $symbolStack[0] eq '(')
|
||||
{
|
||||
$afterParameters .= $token;
|
||||
$isAfterParameters = 1;
|
||||
}
|
||||
else
|
||||
{ $parameter .= $token; };
|
||||
|
||||
pop @symbolStack;
|
||||
}
|
||||
|
||||
elsif ($token eq ',')
|
||||
{
|
||||
if (!scalar @symbolStack)
|
||||
{
|
||||
if ($noParenthesisParameters)
|
||||
{
|
||||
push @parameterLines, $parameter . $token;
|
||||
$parameter = undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
$beforeParameters .= $token;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scalar @symbolStack == 1 && $symbolStack[0] eq '(' && !$noParenthesisParameters)
|
||||
{
|
||||
push @parameterLines, $parameter . $token;
|
||||
$parameter = undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parameter .= $token;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ($noParenthesisParameters || $symbolStack[0] eq '(')
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
};
|
||||
};
|
||||
|
||||
push @parameterLines, $parameter;
|
||||
|
||||
foreach my $item (\$beforeParameters, \$afterParameters)
|
||||
{
|
||||
$$item =~ s/^ //;
|
||||
$$item =~ s/ $//;
|
||||
}
|
||||
|
||||
my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
|
||||
|
||||
|
||||
# Parse the actual parameters.
|
||||
|
||||
foreach my $parameterLine (@parameterLines)
|
||||
{
|
||||
$prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
|
||||
};
|
||||
|
||||
return $prototypeObject;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseParameterLine
|
||||
#
|
||||
# Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
|
||||
#
|
||||
sub ParseParameterLine #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
|
||||
$line =~ s/^ //;
|
||||
$line =~ s/ $//;
|
||||
|
||||
my @tokens = $line =~ /([^\(\)\[\]\{\}\<\>\'\"\:\=\ ]+|\:\=|.)/g;
|
||||
|
||||
my ($name, $type, $defaultValue, $defaultValuePrefix, $inType, $inDefaultValue);
|
||||
|
||||
|
||||
my @symbolStack;
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($inDefaultValue)
|
||||
{ $defaultValue .= $token; }
|
||||
|
||||
elsif ($symbolStack[-1] eq '\'' || $symbolStack[-1] eq '"')
|
||||
{
|
||||
if ($inType)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
|
||||
if ($token eq $symbolStack[-1])
|
||||
{ pop @symbolStack; };
|
||||
}
|
||||
|
||||
elsif ($token =~ /^[\(\[\{\<\'\"]$/)
|
||||
{
|
||||
if ($inType)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
|
||||
push @symbolStack, $token;
|
||||
}
|
||||
|
||||
elsif ( ($token eq ')' && $symbolStack[-1] eq '(') ||
|
||||
($token eq ']' && $symbolStack[-1] eq '[') ||
|
||||
($token eq '}' && $symbolStack[-1] eq '{') ||
|
||||
($token eq '>' && $symbolStack[-1] eq '<') )
|
||||
{
|
||||
if ($inType)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
|
||||
pop @symbolStack;
|
||||
}
|
||||
|
||||
elsif ($token eq ' ')
|
||||
{
|
||||
if ($inType)
|
||||
{ $type .= $token; }
|
||||
elsif (!scalar @symbolStack)
|
||||
{ $inType = 1; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
}
|
||||
|
||||
elsif ($token eq ':=' || $token eq '=')
|
||||
{
|
||||
if (!scalar @symbolStack)
|
||||
{
|
||||
$defaultValuePrefix = $token;
|
||||
$inDefaultValue = 1;
|
||||
}
|
||||
elsif ($inType)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ($inType)
|
||||
{ $type .= $token; }
|
||||
else
|
||||
{ $name .= $token; };
|
||||
};
|
||||
};
|
||||
|
||||
foreach my $part (\$type, \$defaultValue)
|
||||
{
|
||||
$$part =~ s/ $//;
|
||||
};
|
||||
|
||||
return NaturalDocs::Languages::Prototype::Parameter->New($type, undef, $name, undef, $defaultValue, $defaultValuePrefix);
|
||||
};
|
||||
|
||||
|
||||
sub TypeBeforeParameter
|
||||
{ return 0; };
|
||||
|
||||
1;
|
144
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Pascal.pm
Executable file
144
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Pascal.pm
Executable file
@ -0,0 +1,144 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Pascal
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A subclass to handle the language variations of Pascal and Delphi.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Pascal;
|
||||
|
||||
use base 'NaturalDocs::Languages::Simple';
|
||||
|
||||
|
||||
#
|
||||
# hash: prototypeDirectives
|
||||
#
|
||||
# An existence hash of all the directives that can appear after a function prototype and will be included. The keys are the all
|
||||
# lowercase keywords.
|
||||
#
|
||||
my %prototypeDirectives = ( 'overload' => 1,
|
||||
'override' => 1,
|
||||
'virtual' => 1,
|
||||
'abstract' => 1,
|
||||
'reintroduce' => 1,
|
||||
'export' => 1,
|
||||
'public' => 1,
|
||||
'interrupt' => 1,
|
||||
'register' => 1,
|
||||
'pascal' => 1,
|
||||
'cdecl' => 1,
|
||||
'stdcall' => 1,
|
||||
'popstack' => 1,
|
||||
'saveregisters' => 1,
|
||||
'inline' => 1,
|
||||
'safecall' => 1 );
|
||||
|
||||
#
|
||||
# hash: longPrototypeDirectives
|
||||
#
|
||||
# An existence hash of all the directives with parameters that can appear after a function prototype and will be included. The
|
||||
# keys are the all lowercase keywords.
|
||||
#
|
||||
my %longPrototypeDirectives = ( 'alias' => 1,
|
||||
'external' => 1 );
|
||||
|
||||
#
|
||||
# bool: checkingForDirectives
|
||||
#
|
||||
# Set after the first function semicolon, which means we're in directives mode.
|
||||
#
|
||||
my $checkingForDirectives;
|
||||
|
||||
|
||||
#
|
||||
# Function: OnCode
|
||||
#
|
||||
# Just overridden to reset <checkingForDirectives>.
|
||||
#
|
||||
sub OnCode #(...)
|
||||
{
|
||||
my ($self, @parameters) = @_;
|
||||
|
||||
$checkingForDirectives = 0;
|
||||
|
||||
return $self->SUPER::OnCode(@parameters);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnPrototypeEnd
|
||||
#
|
||||
# Pascal's syntax has directives after the prototype that should be included.
|
||||
#
|
||||
# > function MyFunction ( param1: type ); virtual; abstract;
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> of the prototype.
|
||||
# prototypeRef - A reference to the prototype so far, minus the ender in dispute.
|
||||
# ender - The ender symbol.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# ENDER_ACCEPT - The ender is accepted and the prototype is finished.
|
||||
# ENDER_IGNORE - The ender is rejected and parsing should continue. Note that the prototype will be rejected as a whole
|
||||
# if all enders are ignored before reaching the end of the code.
|
||||
# ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is. However, the prototype might
|
||||
# also continue on so continue parsing. If there is no accepted ender between here and
|
||||
# the end of the code this version will be accepted instead.
|
||||
# ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed. Use the last accepted
|
||||
# version and end parsing.
|
||||
#
|
||||
sub OnPrototypeEnd #(type, prototypeRef, ender)
|
||||
{
|
||||
my ($self, $type, $prototypeRef, $ender) = @_;
|
||||
|
||||
if ($type eq ::TOPIC_FUNCTION() && $ender eq ';')
|
||||
{
|
||||
if (!$checkingForDirectives)
|
||||
{
|
||||
$checkingForDirectives = 1;
|
||||
return ::ENDER_ACCEPT_AND_CONTINUE();
|
||||
}
|
||||
elsif ($$prototypeRef =~ /;[ \t]*([a-z]+)([^;]*)$/i)
|
||||
{
|
||||
my ($lastDirective, $extra) = (lc($1), $2);
|
||||
|
||||
if (exists $prototypeDirectives{$lastDirective} && $extra =~ /^[ \t]*$/)
|
||||
{ return ::ENDER_ACCEPT_AND_CONTINUE(); }
|
||||
elsif (exists $longPrototypeDirectives{$lastDirective})
|
||||
{ return ::ENDER_ACCEPT_AND_CONTINUE(); }
|
||||
else
|
||||
{ return ::ENDER_REVERT_TO_ACCEPTED(); };
|
||||
}
|
||||
else
|
||||
{ return ::ENDER_REVERT_TO_ACCEPTED(); };
|
||||
}
|
||||
else
|
||||
{ return ::ENDER_ACCEPT(); };
|
||||
};
|
||||
|
||||
|
||||
sub ParseParameterLine #(...)
|
||||
{
|
||||
my ($self, @params) = @_;
|
||||
return $self->SUPER::ParsePascalParameterLine(@params);
|
||||
};
|
||||
|
||||
sub TypeBeforeParameter
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
1;
|
1371
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Perl.pm
Executable file
1371
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Perl.pm
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,93 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Prototype
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A data class for storing parsed prototypes.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use NaturalDocs::Languages::Prototype::Parameter;
|
||||
|
||||
|
||||
package NaturalDocs::Languages::Prototype;
|
||||
|
||||
use NaturalDocs::DefineMembers 'BEFORE_PARAMETERS', 'BeforeParameters()', 'SetBeforeParameters()',
|
||||
'AFTER_PARAMETERS', 'AfterParameters()', 'SetAfterParameters()',
|
||||
'PARAMETERS', 'Parameters()';
|
||||
# Dependency: New(), constant order, no parents.
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new prototype object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# beforeParameters - The part of the prototype before the parameter list.
|
||||
# afterParameters - The part of the prototype after the parameter list.
|
||||
#
|
||||
# You cannot set the parameters from here. Use <AddParameter()>.
|
||||
#
|
||||
sub New #(beforeParameters, afterParameters)
|
||||
{
|
||||
my ($package, @params) = @_;
|
||||
|
||||
# Dependency: Constant order, no parents.
|
||||
|
||||
my $object = [ @params ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Members
|
||||
#
|
||||
# BeforeParameters - Returns the part of the prototype before the parameter list. If there is no parameter list, this will be the
|
||||
# only thing that returns content.
|
||||
# SetBeforeParameters - Replaces the part of the prototype before the parameter list.
|
||||
# AfterParameters - Returns the part of the prototype after the parameter list, if any.
|
||||
# SetAfterParameters - Replaces the part of the prototype after the parameter list.
|
||||
# Parameters - Returns the parameter list as an arrayref of <NaturalDocs::Languages::Prototype::Parameters>, or undef if none.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: AddParameter
|
||||
#
|
||||
# Adds a <NaturalDocs::Languages::Prototype::Parameter> to the list.
|
||||
#
|
||||
sub AddParameter #(parameter)
|
||||
{
|
||||
my ($self, $parameter) = @_;
|
||||
|
||||
if (!defined $self->[PARAMETERS])
|
||||
{ $self->[PARAMETERS] = [ ]; };
|
||||
|
||||
push @{$self->[PARAMETERS]}, $parameter;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnlyBeforeParameters
|
||||
#
|
||||
# Returns whether <BeforeParameters()> is the only thing set.
|
||||
#
|
||||
sub OnlyBeforeParameters
|
||||
{
|
||||
my $self = shift;
|
||||
return (!defined $self->[PARAMETERS] && !defined $self->[AFTER_PARAMETERS]);
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,88 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Prototype::Parameter
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A data class for storing parsed prototype parameters.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Prototype::Parameter;
|
||||
|
||||
use NaturalDocs::DefineMembers 'TYPE', 'Type()', 'SetType()',
|
||||
'TYPE_PREFIX', 'TypePrefix()', 'SetTypePrefix()',
|
||||
'NAME', 'Name()', 'SetName()',
|
||||
'NAME_PREFIX', 'NamePrefix()', 'SetNamePrefix()',
|
||||
'DEFAULT_VALUE', 'DefaultValue()', 'SetDefaultValue()',
|
||||
'DEFAULT_VALUE_PREFIX', 'DefaultValuePrefix()', 'SetDefaultValuePrefix()';
|
||||
# Dependency: New() depends on the order of these constants and that they don't inherit from another class.
|
||||
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The object is implemented as a blessed arrayref, with the following constants as its indexes.
|
||||
#
|
||||
# TYPE - The parameter type, if any.
|
||||
# TYPE_PREFIX - The parameter type prefix which should be aligned separately, if any.
|
||||
# NAME - The parameter name.
|
||||
# NAME_PREFIX - The parameter name prefix which should be aligned separately, if any.
|
||||
# DEFAULT_VALUE - The default value expression, if any.
|
||||
# DEFAULT_VALUE_PREFIX - The default value prefix which should be aligned separately, if any.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new prototype object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The parameter type, if any.
|
||||
# typePrefix - The parameter type prefix which should be aligned separately, if any.
|
||||
# name - The parameter name.
|
||||
# namePrefix - The parameter name prefix which should be aligned separately, if any.
|
||||
# defaultValue - The default value expression, if any.
|
||||
# defaultValuePrefix - The default value prefix which should be aligned separately, if any.
|
||||
#
|
||||
sub New #(type, typePrefix, name, namePrefix, defaultValue, defaultValuePrefix)
|
||||
{
|
||||
my ($package, @params) = @_;
|
||||
|
||||
# Dependency: This depends on the order of the parameters being the same as the order of the constants, and that the
|
||||
# constants don't inherit from another class.
|
||||
|
||||
my $object = [ @params ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Members
|
||||
#
|
||||
# Type - The parameter type, if any.
|
||||
# SetType - Replaces the parameter type.
|
||||
# TypePrefix - The parameter type prefix, which should be aligned separately, if any.
|
||||
# SetTypePrefix - Replaces the parameter type prefix.
|
||||
# Name - The parameter name.
|
||||
# SetName - Replaces the parameter name.
|
||||
# NamePrefix - The parameter name prefix, which should be aligned separately, if any.
|
||||
# SetNamePrefix - Replaces the parameter name prefix.
|
||||
# DefaultValue - The default value expression, if any.
|
||||
# SetDefaultValue - Replaces the default value expression.
|
||||
# DefaultValuePrefix - The default value prefix, which should be aligned separately, if any.
|
||||
# SetDefaultValuePrefix - Replaces the default value prefix.
|
||||
#
|
||||
|
||||
|
||||
1;
|
487
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Simple.pm
Executable file
487
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Simple.pm
Executable file
@ -0,0 +1,487 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Simple
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class containing the characteristics of a particular programming language for basic support within Natural Docs.
|
||||
# Also serves as a base class for languages that break from general conventions, such as not having parameter lists use
|
||||
# parenthesis and commas.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Simple;
|
||||
|
||||
use base 'NaturalDocs::Languages::Base';
|
||||
use base 'Exporter';
|
||||
|
||||
our @EXPORT = ( 'ENDER_ACCEPT', 'ENDER_IGNORE', 'ENDER_ACCEPT_AND_CONTINUE', 'ENDER_REVERT_TO_ACCEPTED' );
|
||||
|
||||
|
||||
use NaturalDocs::DefineMembers 'LINE_COMMENT_SYMBOLS', 'LineCommentSymbols()', 'SetLineCommentSymbols() duparrayref',
|
||||
'BLOCK_COMMENT_SYMBOLS', 'BlockCommentSymbols()',
|
||||
'SetBlockCommentSymbols() duparrayref',
|
||||
'PROTOTYPE_ENDERS',
|
||||
'LINE_EXTENDER', 'LineExtender()', 'SetLineExtender()',
|
||||
'PACKAGE_SEPARATOR', 'PackageSeparator()',
|
||||
'PACKAGE_SEPARATOR_WAS_SET', 'PackageSeparatorWasSet()',
|
||||
'ENUM_VALUES', 'EnumValues()',
|
||||
'ENUM_VALUES_WAS_SET', 'EnumValuesWasSet()';
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# name - The name of the language.
|
||||
#
|
||||
sub New #(name)
|
||||
{
|
||||
my ($selfPackage, $name) = @_;
|
||||
|
||||
my $object = $selfPackage->SUPER::New($name);
|
||||
|
||||
$object->[ENUM_VALUES] = ::ENUM_GLOBAL();
|
||||
$object->[PACKAGE_SEPARATOR] = '.';
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Members
|
||||
#
|
||||
# LineCommentSymbols - Returns an arrayref of symbols that start a line comment, or undef if none.
|
||||
# SetLineCommentSymbols - Replaces the arrayref of symbols that start a line comment.
|
||||
# BlockCommentSymbols - Returns an arrayref of start/end symbol pairs that specify a block comment, or undef if none. Pairs
|
||||
# are specified with two consecutive array entries.
|
||||
# SetBlockCommentSymbols - Replaces the arrayref of start/end symbol pairs that specify a block comment. Pairs are
|
||||
# specified with two consecutive array entries.
|
||||
# LineExtender - Returns the symbol to ignore a line break in languages where line breaks are significant.
|
||||
# SetLineExtender - Replaces the symbol to ignore a line break in languages where line breaks are significant.
|
||||
# PackageSeparator - Returns the package separator symbol.
|
||||
# PackageSeparatorWasSet - Returns whether the package separator symbol was ever changed from the default.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: SetPackageSeparator
|
||||
# Replaces the language's package separator string.
|
||||
#
|
||||
sub SetPackageSeparator #(separator)
|
||||
{
|
||||
my ($self, $separator) = @_;
|
||||
$self->[PACKAGE_SEPARATOR] = $separator;
|
||||
$self->[PACKAGE_SEPARATOR_WAS_SET] = 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Members
|
||||
#
|
||||
# EnumValues - Returns the <EnumValuesType> that describes how the language handles enums.
|
||||
# EnumValuesWasSet - Returns whether <EnumValues> was ever changed from the default.
|
||||
|
||||
|
||||
#
|
||||
# Function: SetEnumValues
|
||||
# Replaces the <EnumValuesType> that describes how the language handles enums.
|
||||
#
|
||||
sub SetEnumValues #(EnumValuesType newBehavior)
|
||||
{
|
||||
my ($self, $behavior) = @_;
|
||||
$self->[ENUM_VALUES] = $behavior;
|
||||
$self->[ENUM_VALUES_WAS_SET] = 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PrototypeEndersFor
|
||||
#
|
||||
# Returns an arrayref of prototype ender symbols for the passed <TopicType>, or undef if none.
|
||||
#
|
||||
sub PrototypeEndersFor #(type)
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
|
||||
if (defined $self->[PROTOTYPE_ENDERS])
|
||||
{ return $self->[PROTOTYPE_ENDERS]->{$type}; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetPrototypeEndersFor
|
||||
#
|
||||
# Replaces the arrayref of prototype ender symbols for the passed <TopicType>.
|
||||
#
|
||||
sub SetPrototypeEndersFor #(type, enders)
|
||||
{
|
||||
my ($self, $type, $enders) = @_;
|
||||
|
||||
if (!defined $self->[PROTOTYPE_ENDERS])
|
||||
{ $self->[PROTOTYPE_ENDERS] = { }; };
|
||||
|
||||
if (!defined $enders)
|
||||
{ delete $self->[PROTOTYPE_ENDERS]->{$type}; }
|
||||
else
|
||||
{
|
||||
$self->[PROTOTYPE_ENDERS]->{$type} = [ @$enders ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Parsing Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseFile
|
||||
#
|
||||
# Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>
|
||||
# and all other sections to <OnCode()>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# sourceFile - The <FileName> of the source file to parse.
|
||||
# topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Since this class cannot automatically document the code or generate a scope record, it always returns ( undef, undef ).
|
||||
#
|
||||
sub ParseFile #(sourceFile, topicsList)
|
||||
{
|
||||
my ($self, $sourceFile, $topicsList) = @_;
|
||||
|
||||
open(SOURCEFILEHANDLE, '<' . $sourceFile)
|
||||
or die "Couldn't open input file " . $sourceFile . "\n";
|
||||
|
||||
my $lineReader = NaturalDocs::LineReader->New(\*SOURCEFILEHANDLE);
|
||||
|
||||
my @commentLines;
|
||||
my @codeLines;
|
||||
my $lastCommentTopicCount = 0;
|
||||
|
||||
if ($self->Name() eq 'Text File')
|
||||
{
|
||||
@commentLines = $lineReader->GetAll();
|
||||
NaturalDocs::Parser->OnComment(\@commentLines, 1);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
my $line = $lineReader->Get();
|
||||
my $lineNumber = 1;
|
||||
|
||||
while (defined $line)
|
||||
{
|
||||
my $originalLine = $line;
|
||||
|
||||
|
||||
# Retrieve multiline comments. This leaves $line at the next line.
|
||||
# We check for multiline comments before single line comments because in Lua the symbols are --[[ and --.
|
||||
|
||||
if (my $closingSymbol = $self->StripOpeningBlockSymbols(\$line, $self->BlockCommentSymbols()))
|
||||
{
|
||||
# Note that it is possible for a multiline comment to start correctly but not end so. We want those comments to stay in
|
||||
# the code. For example, look at this prototype with this splint annotation:
|
||||
#
|
||||
# int get_array(integer_t id,
|
||||
# /*@out@*/ array_t array);
|
||||
#
|
||||
# The annotation starts correctly but doesn't end so because it is followed by code on the same line.
|
||||
|
||||
my $lineRemainder;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
$lineRemainder = $self->StripClosingSymbol(\$line, $closingSymbol);
|
||||
|
||||
push @commentLines, $line;
|
||||
|
||||
# If we found an end comment symbol...
|
||||
if (defined $lineRemainder)
|
||||
{ last; };
|
||||
|
||||
$line = $lineReader->Get();
|
||||
|
||||
if (!defined $line)
|
||||
{ last; };
|
||||
};
|
||||
|
||||
if ($lineRemainder !~ /^[ \t]*$/)
|
||||
{
|
||||
# If there was something past the closing symbol this wasn't an acceptable comment, so move the lines to code.
|
||||
push @codeLines, @commentLines;
|
||||
@commentLines = ( );
|
||||
};
|
||||
|
||||
$line = $lineReader->Get();
|
||||
}
|
||||
|
||||
|
||||
# Retrieve single line comments. This leaves $line at the next line.
|
||||
|
||||
elsif ($self->StripOpeningSymbols(\$line, $self->LineCommentSymbols()))
|
||||
{
|
||||
do
|
||||
{
|
||||
push @commentLines, $line;
|
||||
$line = $lineReader->Get();
|
||||
|
||||
if (!defined $line)
|
||||
{ goto EndDo; };
|
||||
}
|
||||
while ($self->StripOpeningSymbols(\$line, $self->LineCommentSymbols()));
|
||||
|
||||
EndDo: # I hate Perl sometimes.
|
||||
}
|
||||
|
||||
|
||||
# Otherwise just add it to the code.
|
||||
|
||||
else
|
||||
{
|
||||
push @codeLines, $line;
|
||||
$line = $lineReader->Get();
|
||||
};
|
||||
|
||||
|
||||
# If there were comments, send them to Parser->OnComment().
|
||||
|
||||
if (scalar @commentLines)
|
||||
{
|
||||
# First process any code lines before the comment.
|
||||
if (scalar @codeLines)
|
||||
{
|
||||
$self->OnCode(\@codeLines, $lineNumber, $topicsList, $lastCommentTopicCount);
|
||||
$lineNumber += scalar @codeLines;
|
||||
@codeLines = ( );
|
||||
};
|
||||
|
||||
$lastCommentTopicCount = NaturalDocs::Parser->OnComment(\@commentLines, $lineNumber);
|
||||
$lineNumber += scalar @commentLines;
|
||||
@commentLines = ( );
|
||||
};
|
||||
|
||||
}; # while (defined $line)
|
||||
|
||||
|
||||
# Clean up any remaining code.
|
||||
if (scalar @codeLines)
|
||||
{
|
||||
$self->OnCode(\@codeLines, $lineNumber, $topicsList, $lastCommentTopicCount);
|
||||
@codeLines = ( );
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
close(SOURCEFILEHANDLE);
|
||||
|
||||
return ( undef, undef );
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnCode
|
||||
#
|
||||
# Called whenever a section of code is encountered by the parser. Is used to find the prototype of the last topic created.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# codeLines - The source code as an arrayref of lines.
|
||||
# codeLineNumber - The line number of the first line of code.
|
||||
# topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
|
||||
# lastCommentTopicCount - The number of Natural Docs topics that were created by the last comment.
|
||||
#
|
||||
sub OnCode #(codeLines, codeLineNumber, topicList, lastCommentTopicCount)
|
||||
{
|
||||
my ($self, $codeLines, $codeLineNumber, $topicList, $lastCommentTopicCount) = @_;
|
||||
|
||||
if ($lastCommentTopicCount && defined $self->PrototypeEndersFor($topicList->[-1]->Type()))
|
||||
{
|
||||
my $lineIndex = 0;
|
||||
my $prototype;
|
||||
|
||||
# Skip all blank lines before a prototype.
|
||||
while ($lineIndex < scalar @$codeLines && $codeLines->[$lineIndex] =~ /^[ \t]*$/)
|
||||
{ $lineIndex++; };
|
||||
|
||||
my @tokens;
|
||||
my $tokenIndex = 0;
|
||||
|
||||
my @brackets;
|
||||
my $enders = $self->PrototypeEndersFor($topicList->[-1]->Type());
|
||||
|
||||
# Add prototype lines until we reach the end of the prototype or the end of the code lines.
|
||||
while ($lineIndex < scalar @$codeLines)
|
||||
{
|
||||
my $line = $self->RemoveLineExtender($codeLines->[$lineIndex] . "\n");
|
||||
|
||||
push @tokens, $line =~ /([^\(\)\[\]\{\}\<\>]+|.)/g;
|
||||
|
||||
while ($tokenIndex < scalar @tokens)
|
||||
{
|
||||
# If we're not inside brackets, check for ender symbols.
|
||||
if (!scalar @brackets)
|
||||
{
|
||||
my $startingIndex = 0;
|
||||
my $testPrototype;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
my ($enderIndex, $ender) = ::FindFirstSymbol($tokens[$tokenIndex], $enders, $startingIndex);
|
||||
|
||||
if ($enderIndex == -1)
|
||||
{ last; }
|
||||
else
|
||||
{
|
||||
# We do this here so we don't duplicate prototype for every single token. Just the first time an ender symbol
|
||||
# is found in one.
|
||||
if (!defined $testPrototype)
|
||||
{ $testPrototype = $prototype; };
|
||||
|
||||
$testPrototype .= substr($tokens[$tokenIndex], $startingIndex, $enderIndex - $startingIndex);
|
||||
|
||||
my $enderResult;
|
||||
|
||||
# If the ender is all text and the character preceding or following it is as well, ignore it.
|
||||
if ($ender =~ /^[a-z0-9]+$/i &&
|
||||
( ($enderIndex > 0 && substr($tokens[$tokenIndex], $enderIndex - 1, 1) =~ /^[a-z0-9_]$/i) ||
|
||||
substr($tokens[$tokenIndex], $enderIndex + length($ender), 1) =~ /^[a-z0-9_]$/i ) )
|
||||
{ $enderResult = ENDER_IGNORE(); }
|
||||
else
|
||||
{ $enderResult = $self->OnPrototypeEnd($topicList->[-1]->Type(), \$testPrototype, $ender); }
|
||||
|
||||
if ($enderResult == ENDER_IGNORE())
|
||||
{
|
||||
$testPrototype .= $ender;
|
||||
$startingIndex = $enderIndex + length($ender);
|
||||
}
|
||||
elsif ($enderResult == ENDER_REVERT_TO_ACCEPTED())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else # ENDER_ACCEPT || ENDER_ACCEPT_AND_CONTINUE
|
||||
{
|
||||
my $titleInPrototype = $topicList->[-1]->Title();
|
||||
|
||||
# Strip parenthesis so Function(2) and Function(int, int) will still match Function(anything).
|
||||
$titleInPrototype =~ s/[\t ]*\([^\(]*$//;
|
||||
|
||||
if (index($testPrototype, $titleInPrototype) != -1)
|
||||
{
|
||||
$topicList->[-1]->SetPrototype( $self->NormalizePrototype($testPrototype) );
|
||||
};
|
||||
|
||||
if ($enderResult == ENDER_ACCEPT())
|
||||
{ return; }
|
||||
else # ENDER_ACCEPT_AND_CONTINUE
|
||||
{
|
||||
$testPrototype .= $ender;
|
||||
$startingIndex = $enderIndex + length($ender);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
# If we are inside brackets, check for closing symbols.
|
||||
elsif ( ($tokens[$tokenIndex] eq ')' && $brackets[-1] eq '(') ||
|
||||
($tokens[$tokenIndex] eq ']' && $brackets[-1] eq '[') ||
|
||||
($tokens[$tokenIndex] eq '}' && $brackets[-1] eq '{') ||
|
||||
($tokens[$tokenIndex] eq '>' && $brackets[-1] eq '<') )
|
||||
{
|
||||
pop @brackets;
|
||||
};
|
||||
|
||||
# Check for opening brackets.
|
||||
if ($tokens[$tokenIndex] =~ /^[\(\[\{]$/ ||
|
||||
($tokens[$tokenIndex] eq "<" && $tokens[$tokenIndex-1] !~ /operator[ \t]*$/) )
|
||||
{
|
||||
push @brackets, $tokens[$tokenIndex];
|
||||
};
|
||||
|
||||
$prototype .= $tokens[$tokenIndex];
|
||||
$tokenIndex++;
|
||||
};
|
||||
|
||||
$lineIndex++;
|
||||
};
|
||||
|
||||
# If we got out of that while loop by running out of lines, there was no prototype.
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
use constant ENDER_ACCEPT => 1;
|
||||
use constant ENDER_IGNORE => 2;
|
||||
use constant ENDER_ACCEPT_AND_CONTINUE => 3;
|
||||
use constant ENDER_REVERT_TO_ACCEPTED => 4;
|
||||
|
||||
#
|
||||
# Function: OnPrototypeEnd
|
||||
#
|
||||
# Called whenever the end of a prototype is found so that there's a chance for derived classes to mark false positives.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> of the prototype.
|
||||
# prototypeRef - A reference to the prototype so far, minus the ender in dispute.
|
||||
# ender - The ender symbol.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# ENDER_ACCEPT - The ender is accepted and the prototype is finished.
|
||||
# ENDER_IGNORE - The ender is rejected and parsing should continue. Note that the prototype will be rejected as a whole
|
||||
# if all enders are ignored before reaching the end of the code.
|
||||
# ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is. However, the prototype might
|
||||
# also continue on so continue parsing. If there is no accepted ender between here and
|
||||
# the end of the code this version will be accepted instead.
|
||||
# ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed. Use the last accepted
|
||||
# version and end parsing.
|
||||
#
|
||||
sub OnPrototypeEnd #(type, prototypeRef, ender)
|
||||
{
|
||||
return ENDER_ACCEPT();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: RemoveLineExtender
|
||||
#
|
||||
# If the passed line has a line extender, returns it without the extender or the line break that follows. If it doesn't, or there are
|
||||
# no line extenders defined, returns the passed line unchanged.
|
||||
#
|
||||
sub RemoveLineExtender #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
|
||||
if (defined $self->LineExtender())
|
||||
{
|
||||
my $lineExtenderIndex = rindex($line, $self->LineExtender());
|
||||
|
||||
if ($lineExtenderIndex != -1 &&
|
||||
substr($line, $lineExtenderIndex + length($self->LineExtender())) =~ /^[ \t]*\n$/)
|
||||
{
|
||||
$line = substr($line, 0, $lineExtenderIndex) . ' ';
|
||||
};
|
||||
};
|
||||
|
||||
return $line;
|
||||
};
|
||||
|
||||
|
||||
1;
|
220
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Tcl.pm
Executable file
220
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Languages/Tcl.pm
Executable file
@ -0,0 +1,220 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Languages::Tcl
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A subclass to handle the language variations of Tcl.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Languages::Tcl;
|
||||
|
||||
use base 'NaturalDocs::Languages::Simple';
|
||||
|
||||
|
||||
#
|
||||
# bool: pastFirstBrace
|
||||
#
|
||||
# Whether we've past the first brace in a function prototype or not.
|
||||
#
|
||||
my $pastFirstBrace;
|
||||
|
||||
|
||||
#
|
||||
# Function: OnCode
|
||||
#
|
||||
# This is just overridden to reset <pastFirstBrace>.
|
||||
#
|
||||
sub OnCode #(...)
|
||||
{
|
||||
my ($self, @params) = @_;
|
||||
|
||||
$pastFirstBrace = 0;
|
||||
|
||||
return $self->SUPER::OnCode(@params);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnPrototypeEnd
|
||||
#
|
||||
# Tcl's function syntax is shown below.
|
||||
#
|
||||
# > proc [name] { [params] } { [code] }
|
||||
#
|
||||
# The opening brace is one of the prototype enders. We need to allow the first opening brace because it contains the
|
||||
# parameters.
|
||||
#
|
||||
# Also, the parameters may have braces within them. I've seen one that used { seconds 20 } as a parameter.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType> of the prototype.
|
||||
# prototypeRef - A reference to the prototype so far, minus the ender in dispute.
|
||||
# ender - The ender symbol.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# ENDER_ACCEPT - The ender is accepted and the prototype is finished.
|
||||
# ENDER_IGNORE - The ender is rejected and parsing should continue. Note that the prototype will be rejected as a whole
|
||||
# if all enders are ignored before reaching the end of the code.
|
||||
# ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is. However, the prototype might
|
||||
# also continue on so continue parsing. If there is no accepted ender between here and
|
||||
# the end of the code this version will be accepted instead.
|
||||
# ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed. Use the last accepted
|
||||
# version and end parsing.
|
||||
#
|
||||
sub OnPrototypeEnd #(type, prototypeRef, ender)
|
||||
{
|
||||
my ($self, $type, $prototypeRef, $ender) = @_;
|
||||
|
||||
if ($type eq ::TOPIC_FUNCTION() && $ender eq '{' && !$pastFirstBrace)
|
||||
{
|
||||
$pastFirstBrace = 1;
|
||||
return ::ENDER_IGNORE();
|
||||
}
|
||||
else
|
||||
{ return ::ENDER_ACCEPT(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParsePrototype
|
||||
#
|
||||
# Parses the prototype and returns it as a <NaturalDocs::Languages::Prototype> object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType>.
|
||||
# prototype - The text prototype.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# A <NaturalDocs::Languages::Prototype> object.
|
||||
#
|
||||
sub ParsePrototype #(type, prototype)
|
||||
{
|
||||
my ($self, $type, $prototype) = @_;
|
||||
|
||||
if ($type ne ::TOPIC_FUNCTION())
|
||||
{
|
||||
my $object = NaturalDocs::Languages::Prototype->New($prototype);
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Parse the parameters out of the prototype.
|
||||
|
||||
my @tokens = $prototype =~ /([^\{\}\ ]+|.)/g;
|
||||
|
||||
my $parameter;
|
||||
my @parameterLines;
|
||||
|
||||
my $braceLevel = 0;
|
||||
|
||||
my ($beforeParameters, $afterParameters, $finishedParameters);
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($finishedParameters)
|
||||
{ $afterParameters .= $token; }
|
||||
|
||||
elsif ($token eq '{')
|
||||
{
|
||||
if ($braceLevel == 0)
|
||||
{ $beforeParameters .= $token; }
|
||||
|
||||
else # braceLevel > 0
|
||||
{ $parameter .= $token; };
|
||||
|
||||
$braceLevel++;
|
||||
}
|
||||
|
||||
elsif ($token eq '}')
|
||||
{
|
||||
if ($braceLevel == 1)
|
||||
{
|
||||
if ($parameter && $parameter ne ' ')
|
||||
{ push @parameterLines, $parameter; };
|
||||
|
||||
$finishedParameters = 1;
|
||||
$afterParameters .= $token;
|
||||
|
||||
$braceLevel--;
|
||||
}
|
||||
elsif ($braceLevel > 1)
|
||||
{
|
||||
$parameter .= $token;
|
||||
$braceLevel--;
|
||||
};
|
||||
}
|
||||
|
||||
elsif ($token eq ' ')
|
||||
{
|
||||
if ($braceLevel == 1)
|
||||
{
|
||||
if ($parameter)
|
||||
{ push @parameterLines, $parameter; };
|
||||
|
||||
$parameter = undef;
|
||||
}
|
||||
elsif ($braceLevel > 1)
|
||||
{
|
||||
$parameter .= $token;
|
||||
}
|
||||
else
|
||||
{
|
||||
$beforeParameters .= $token;
|
||||
};
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ($braceLevel > 0)
|
||||
{ $parameter .= $token; }
|
||||
else
|
||||
{ $beforeParameters .= $token; };
|
||||
};
|
||||
};
|
||||
|
||||
foreach my $part (\$beforeParameters, \$afterParameters)
|
||||
{
|
||||
$$part =~ s/^ //;
|
||||
$$part =~ s/ $//;
|
||||
};
|
||||
|
||||
my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
|
||||
|
||||
|
||||
# Parse the actual parameters.
|
||||
|
||||
foreach my $parameterLine (@parameterLines)
|
||||
{
|
||||
$prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
|
||||
};
|
||||
|
||||
return $prototypeObject;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ParseParameterLine
|
||||
#
|
||||
# Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
|
||||
#
|
||||
sub ParseParameterLine #(line)
|
||||
{
|
||||
my ($self, $line) = @_;
|
||||
return NaturalDocs::Languages::Prototype::Parameter->New(undef, undef, $line, undef, undef, undef);
|
||||
};
|
||||
|
||||
|
||||
1;
|
192
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/LineReader.pm
Executable file
192
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/LineReader.pm
Executable file
@ -0,0 +1,192 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::LineReader
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# An object to handle reading text files line by line in a cross platform manner. Using this class instead of the standard
|
||||
# angle brackets approach has the following benefits:
|
||||
#
|
||||
# - It strips all three types of line breaks automatically: CR/LF (Windows) LF (Unix) and CR (Classic Mac). You do not need to
|
||||
# call chomp(). Perl's chomp() fails when parsing Windows-format line breaks on a Unix platform anyway. It leaves the /r on,
|
||||
# which screws everything up.
|
||||
# - It reads Classic Mac files line by line correctly, whereas the Perl version returns it all as one line.
|
||||
# - It abstracts away ignoring the Unicode BOM on the first line, if present.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
use Encode;
|
||||
|
||||
|
||||
package NaturalDocs::LineReader;
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# LINEREADER_FILEHANDLE - The file handle being used to read the file. Has the LINEREADER_ prefix to make sure it doesn't
|
||||
# conflict with any actual filehandles named FILEHANDLE in the program.
|
||||
# CACHED_LINES - An arrayref of lines already read into memory.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'LINEREADER_FILEHANDLE',
|
||||
'CACHED_LINES';
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# filehandle - The file handle being used to read the file.
|
||||
#
|
||||
sub New #(filehandle)
|
||||
{
|
||||
my ($selfPackage, $filehandle) = @_;
|
||||
|
||||
my $object = [ ];
|
||||
|
||||
$object->[LINEREADER_FILEHANDLE] = $filehandle;
|
||||
$object->[CACHED_LINES] = [ ];
|
||||
|
||||
binmode($filehandle, ':raw');
|
||||
|
||||
my $hasBOM = 0;
|
||||
my $possibleBOM = undef;
|
||||
read($filehandle, $possibleBOM, 2);
|
||||
|
||||
if ($possibleBOM eq "\xEF\xBB")
|
||||
{
|
||||
read($filehandle, $possibleBOM, 1);
|
||||
if ($possibleBOM eq "\xBF")
|
||||
{
|
||||
binmode($filehandle, ':crlf:encoding(UTF-8)'); # Strict UTF-8, not Perl's lax version.
|
||||
$hasBOM = 1;
|
||||
}
|
||||
}
|
||||
elsif ($possibleBOM eq "\xFE\xFF")
|
||||
{
|
||||
binmode($filehandle, ':crlf:encoding(UTF-16BE)');
|
||||
$hasBOM = 1;
|
||||
}
|
||||
elsif ($possibleBOM eq "\xFF\xFE")
|
||||
{
|
||||
binmode($filehandle, ':crlf:encoding(UTF-16LE)');
|
||||
$hasBOM = 1;
|
||||
}
|
||||
|
||||
if (!$hasBOM)
|
||||
{
|
||||
seek($filehandle, 0, 0);
|
||||
|
||||
my $rawData = undef;
|
||||
my $readLength = -s $filehandle;
|
||||
|
||||
# Since we're only reading the data to determine if it's UTF-8, sanity check the file length. We may run
|
||||
# across a huge extensionless system file and we don't want to load the whole thing. Half a meg should
|
||||
# be good enough to encompass giant source files while not bogging things down on system files.
|
||||
if ($readLength > 512 * 1024)
|
||||
{ $readLength = 512 * 1024; }
|
||||
|
||||
read($filehandle, $rawData, $readLength);
|
||||
|
||||
eval
|
||||
{ $rawData = Encode::decode("UTF-8", $rawData, Encode::FB_CROAK); };
|
||||
|
||||
if ($::EVAL_ERROR)
|
||||
{ binmode($filehandle, ':crlf'); }
|
||||
else
|
||||
{
|
||||
# Theoretically, since this is valid UTF-8 data we should be able to split it on line breaks and feed them into
|
||||
# CACHED_LINES instead of setting the encoding to UTF-8 and seeking back to zero just to read it all again.
|
||||
# Alas, this doesn't work for an easily identifiable reason. I'm sure there is one, but I couldn't figure it out
|
||||
# before my patience ran out so I'm just letting the file cache absorb the hit instead. If we were ever to do
|
||||
# this in the future you'd have to handle the file length capping code above too.
|
||||
binmode($filehandle, ':crlf:encoding(UTF-8)');
|
||||
}
|
||||
|
||||
seek($filehandle, 0, 0);
|
||||
}
|
||||
|
||||
bless $object, $selfPackage;
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Chomp
|
||||
#
|
||||
# Removes any line breaks from the end of a value. It does not remove any that are in the middle of it.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lineRef - A *reference* to the line to chomp.
|
||||
#
|
||||
sub Chomp #(lineRef)
|
||||
{
|
||||
my ($self, $lineRef) = @_;
|
||||
$$lineRef =~ s/(?:\r\n|\r|\n)$//;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Get
|
||||
#
|
||||
# Returns the next line of text from the file, or undef if there are no more. The line break will be removed automatically. If
|
||||
# the first line contains a Unicode BOM, that will also be removed automatically.
|
||||
#
|
||||
sub Get
|
||||
{
|
||||
my $self = shift;
|
||||
my $line = undef;
|
||||
|
||||
if (scalar @{$self->[CACHED_LINES]} == 0)
|
||||
{
|
||||
my $filehandle = $self->[LINEREADER_FILEHANDLE];
|
||||
my $rawLine = <$filehandle>;
|
||||
|
||||
if (!defined $rawLine)
|
||||
{ return undef; }
|
||||
|
||||
$self->Chomp(\$rawLine);
|
||||
|
||||
if ($rawLine =~ /\r/)
|
||||
{
|
||||
push @{$self->[CACHED_LINES]}, split(/\r/, $rawLine); # Split for Classic Mac
|
||||
$line = shift @{$self->[CACHED_LINES]};
|
||||
}
|
||||
else
|
||||
{ $line = $rawLine; }
|
||||
}
|
||||
else
|
||||
{ $line = shift @{$self->[CACHED_LINES]}; }
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Function: GetAll
|
||||
#
|
||||
# Returns an array of all the lines from the file. The line breaks will be removed automatically. If the first line contains a
|
||||
# Unicode BOM, that will also be removed automatically.
|
||||
#
|
||||
sub GetAll
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $filehandle = $self->[LINEREADER_FILEHANDLE];
|
||||
my $rawContent;
|
||||
|
||||
read($filehandle, $rawContent, -s $filehandle);
|
||||
|
||||
return split(/\r\n|\n|\r/, $rawContent);
|
||||
}
|
||||
|
||||
1;
|
3430
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu.pm
Executable file
3430
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu.pm
Executable file
File diff suppressed because it is too large
Load Diff
202
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu/Entry.pm
Executable file
202
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Menu/Entry.pm
Executable file
@ -0,0 +1,202 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Menu::Entry
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing an entry in the menu.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Menu::Entry;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The object is implemented as a blessed arrayref with the indexes below.
|
||||
#
|
||||
# TYPE - The <MenuEntryType>
|
||||
# TITLE - The title of the entry.
|
||||
# TARGET - The target of the entry. If the type is <MENU_FILE>, it will be the source <FileName>. If the type is
|
||||
# <MENU_LINK>, it will be the URL. If the type is <MENU_GROUP>, it will be an arrayref of
|
||||
# <NaturalDocs::Menu::Entry> objects representing the group's content. If the type is <MENU_INDEX>, it will be
|
||||
# a <TopicType>.
|
||||
# FLAGS - Any <Menu Entry Flags> that apply.
|
||||
#
|
||||
use constant TYPE => 0;
|
||||
use constant TITLE => 1;
|
||||
use constant TARGET => 2;
|
||||
use constant FLAGS => 3;
|
||||
# DEPENDENCY: New() depends on the order of these constants.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <MenuEntryType>.
|
||||
# title - The title of the entry.
|
||||
# target - The target of the entry, if applicable. If the type is <MENU_FILE>, use the source <FileName>. If the type is
|
||||
# <MENU_LINK>, use the URL. If the type is <MENU_INDEX>, use the <TopicType>. Otherwise set it to undef.
|
||||
# flags - Any <Menu Entry Flags> that apply.
|
||||
#
|
||||
sub New #(type, title, target, flags)
|
||||
{
|
||||
# DEPENDENCY: This gode depends on the order of the constants.
|
||||
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
if ($object->[TYPE] == ::MENU_GROUP())
|
||||
{ $object->[TARGET] = [ ]; };
|
||||
if (!defined $object->[FLAGS])
|
||||
{ $object->[FLAGS] = 0; };
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Type
|
||||
# Returns the <MenuEntryType>.
|
||||
sub Type
|
||||
{ return $_[0]->[TYPE]; };
|
||||
|
||||
# Function: Title
|
||||
# Returns the title of the entry.
|
||||
sub Title
|
||||
{ return $_[0]->[TITLE]; };
|
||||
|
||||
# Function: SetTitle
|
||||
# Replaces the entry's title.
|
||||
sub SetTitle #(title)
|
||||
{ $_[0]->[TITLE] = $_[1]; };
|
||||
|
||||
#
|
||||
# Function: Target
|
||||
#
|
||||
# Returns the target of the entry, if applicable. If the type is <MENU_FILE>, it returns the source <FileName>. If the type is
|
||||
# <MENU_LINK>, it returns the URL. If the type is <MENU_INDEX>, it returns the <TopicType>. Otherwise it returns undef.
|
||||
#
|
||||
sub Target
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
# Group entries are the only time when target won't be undef when it should be.
|
||||
if ($self->Type() == ::MENU_GROUP())
|
||||
{ return undef; }
|
||||
else
|
||||
{ return $self->[TARGET]; };
|
||||
};
|
||||
|
||||
# Function: SetTarget
|
||||
# Replaces the entry's target.
|
||||
sub SetTarget #(target)
|
||||
{ $_[0]->[TARGET] = $_[1]; };
|
||||
|
||||
# Function: Flags
|
||||
# Returns the <Menu Entry Flags>.
|
||||
sub Flags
|
||||
{ return $_[0]->[FLAGS]; };
|
||||
|
||||
# Function: SetFlags
|
||||
# Replaces the <Menu Entry Flags>.
|
||||
sub SetFlags #(flags)
|
||||
{ $_[0]->[FLAGS] = $_[1]; };
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Group Functions
|
||||
#
|
||||
# All of these functions assume the type is <MENU_GROUP>. Do *not* call any of these without checking <Type()> first.
|
||||
|
||||
|
||||
#
|
||||
# Function: GroupContent
|
||||
#
|
||||
# Returns an arrayref of <NaturalDocs::Menu::Entry> objects representing the contents of the
|
||||
# group, or undef otherwise. This arrayref will always exist for <MENU_GROUP>'s and can be changed.
|
||||
#
|
||||
sub GroupContent
|
||||
{
|
||||
return $_[0]->[TARGET];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GroupIsEmpty
|
||||
#
|
||||
# If the type is <MENU_GROUP>, returns whether the group is empty.
|
||||
#
|
||||
sub GroupIsEmpty
|
||||
{
|
||||
my $self = shift;
|
||||
return (scalar @{$self->GroupContent()} > 0);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PushToGroup
|
||||
#
|
||||
# Pushes the entry to the end of the group content.
|
||||
#
|
||||
sub PushToGroup #(entry)
|
||||
{
|
||||
my ($self, $entry) = @_;
|
||||
push @{$self->GroupContent()}, $entry;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteFromGroup
|
||||
#
|
||||
# Deletes an entry from the group content by index.
|
||||
#
|
||||
sub DeleteFromGroup #(index)
|
||||
{
|
||||
my ($self, $index) = @_;
|
||||
|
||||
my $groupContent = $self->GroupContent();
|
||||
|
||||
splice( @$groupContent, $index, 1 );
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: MarkEndOfOriginal
|
||||
#
|
||||
# If the group doesn't already have one, adds a <MENU_ENDOFORIGINAL> entry to the end and sets the
|
||||
# <MENU_GROUP_HASENDOFORIGINAL> flag.
|
||||
#
|
||||
sub MarkEndOfOriginal
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (($self->Flags() & ::MENU_GROUP_HASENDOFORIGINAL()) == 0)
|
||||
{
|
||||
$self->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_ENDOFORIGINAL(), undef, undef, undef) );
|
||||
$self->SetFlags( $self->Flags() | ::MENU_GROUP_HASENDOFORIGINAL() );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
77
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/NDMarkup.pm
Executable file
77
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/NDMarkup.pm
Executable file
@ -0,0 +1,77 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::NDMarkup
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package of support functions for dealing with <NDMarkup>.
|
||||
#
|
||||
# Usage and Dependencies:
|
||||
#
|
||||
# The package doesn't depend on any Natural Docs packages and is ready to use right away.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::NDMarkup;
|
||||
|
||||
#
|
||||
# Function: ConvertAmpChars
|
||||
#
|
||||
# Substitutes certain characters with their <NDMarkup> amp chars.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# text - The block of text to convert.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The converted text block.
|
||||
#
|
||||
sub ConvertAmpChars #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$text =~ s/&/&/g;
|
||||
$text =~ s/</</g;
|
||||
$text =~ s/>/>/g;
|
||||
$text =~ s/\"/"/g;
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: RestoreAmpChars
|
||||
#
|
||||
# Replaces <NDMarkup> amp chars with their original symbols.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# text - The text to restore.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The restored text.
|
||||
#
|
||||
sub RestoreAmpChars #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$text =~ s/"/\"/g;
|
||||
$text =~ s/>/>/g;
|
||||
$text =~ s/</</g;
|
||||
$text =~ s/&/&/g;
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
|
||||
1;
|
1335
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser.pm
Executable file
1335
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser.pm
Executable file
File diff suppressed because it is too large
Load Diff
465
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/JavaDoc.pm
Executable file
465
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/JavaDoc.pm
Executable file
@ -0,0 +1,465 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Parser::JavaDoc
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package for translating JavaDoc topics into Natural Docs.
|
||||
#
|
||||
# Supported tags:
|
||||
#
|
||||
# - @param
|
||||
# - @author
|
||||
# - @deprecated
|
||||
# - @code, @literal (doesn't change font)
|
||||
# - @exception, @throws (doesn't link to class)
|
||||
# - @link, @linkplain (doesn't change font)
|
||||
# - @return, @returns
|
||||
# - @see
|
||||
# - @since
|
||||
# - @value (shown as link instead of replacement)
|
||||
# - @version
|
||||
#
|
||||
# Stripped tags:
|
||||
#
|
||||
# - @inheritDoc
|
||||
# - @serial, @serialField, @serialData
|
||||
# - All other block level tags.
|
||||
#
|
||||
# Unsupported tags:
|
||||
#
|
||||
# These will appear literally in the output because I cannot handle them easily.
|
||||
#
|
||||
# - @docRoot
|
||||
# - Any other tags not mentioned
|
||||
#
|
||||
# Supported HTML:
|
||||
#
|
||||
# - p
|
||||
# - b, i, u
|
||||
# - pre
|
||||
# - a href
|
||||
# - ol, ul, li (ol gets converted to ul)
|
||||
# - gt, lt, amp, quot, nbsp entities
|
||||
#
|
||||
# Stripped HTML:
|
||||
#
|
||||
# - code
|
||||
# - HTML comments
|
||||
#
|
||||
# Unsupported HTML:
|
||||
#
|
||||
# These will appear literally in the output because I cannot handle them easily.
|
||||
#
|
||||
# - Any tags with additional properties other than a href. (ex. <p class=Something>)
|
||||
# - Any other tags not mentioned
|
||||
#
|
||||
# Reference:
|
||||
#
|
||||
# http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Parser::JavaDoc;
|
||||
|
||||
|
||||
#
|
||||
# hash: blockTags
|
||||
# An existence hash of the all-lowercase JavaDoc block tags, not including the @.
|
||||
#
|
||||
my %blockTags = ( 'param' => 1, 'author' => 1, 'deprecated' => 1, 'exception' => 1, 'return' => 1, 'see' => 1,
|
||||
'serial' => 1, 'serialfield' => 1, 'serialdata' => 1, 'since' => 1, 'throws' => 1, 'version' => 1,
|
||||
'returns' => 1 );
|
||||
|
||||
#
|
||||
# hash: inlineTags
|
||||
# An existence hash of the all-lowercase JavaDoc inline tags, not including the @.
|
||||
#
|
||||
my %inlineTags = ( 'inheritdoc' => 1, 'docroot' => 1, 'code' => 1, 'literal' => 1, 'link' => 1, 'linkplain' => 1, 'value' => 1 );
|
||||
|
||||
|
||||
##
|
||||
# Examines the comment and returns whether it is *definitely* JavaDoc content, i.e. is owned by this package.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# commentLines - An arrayref of the comment lines. Must have been run through <NaturalDocs::Parser->CleanComment()>.
|
||||
# isJavaDoc - Whether the comment is JavaDoc styled. This doesn't necessarily mean it has JavaDoc content.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the comment is *definitely* JavaDoc content.
|
||||
#
|
||||
sub IsMine #(string[] commentLines, bool isJavaDoc)
|
||||
{
|
||||
my ($self, $commentLines, $isJavaDoc) = @_;
|
||||
|
||||
if (!$isJavaDoc)
|
||||
{ return undef; };
|
||||
|
||||
for (my $line = 0; $line < scalar @$commentLines; $line++)
|
||||
{
|
||||
if ($commentLines->[$line] =~ /^ *@([a-z]+) /i && exists $blockTags{$1} ||
|
||||
$commentLines->[$line] =~ /\{@([a-z]+) /i && exists $inlineTags{$1})
|
||||
{
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
##
|
||||
# Parses the JavaDoc-syntax comment and adds it to the parsed topic list.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# commentLines - An arrayref of the comment lines. Must have been run through <NaturalDocs::Parser->CleanComment()>.
|
||||
# *The original memory will be changed.*
|
||||
# isJavaDoc - Whether the comment is JavaDoc styled. This doesn't necessarily mean it has JavaDoc content.
|
||||
# lineNumber - The line number of the first of the comment lines.
|
||||
# parsedTopics - A reference to the array where any new <NaturalDocs::Parser::ParsedTopics> should be placed.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The number of parsed topics added to the array, which in this case will always be one.
|
||||
#
|
||||
sub ParseComment #(string[] commentLines, bool isJavaDoc, int lineNumber, ParsedTopics[]* parsedTopics)
|
||||
{
|
||||
my ($self, $commentLines, $isJavaDoc, $lineNumber, $parsedTopics) = @_;
|
||||
|
||||
|
||||
# Stage one: Before block level tags.
|
||||
|
||||
my $i = 0;
|
||||
my $output;
|
||||
my $unformattedText;
|
||||
my $inCode;
|
||||
my $sharedCodeIndent;
|
||||
|
||||
while ($i < scalar @$commentLines &&
|
||||
!($commentLines->[$i] =~ /^ *@([a-z]+) /i && exists $blockTags{$1}) )
|
||||
{
|
||||
my $line = $self->ConvertAmpChars($commentLines->[$i]);
|
||||
my @tokens = split(/(<\/?pre>)/, $line);
|
||||
|
||||
foreach my $token (@tokens)
|
||||
{
|
||||
if ($token =~ /^<pre>$/i)
|
||||
{
|
||||
if (!$inCode && $unformattedText)
|
||||
{
|
||||
$output .= '<p>' . $self->FormatText($unformattedText, 1) . '</p>';
|
||||
};
|
||||
|
||||
$inCode = 1;
|
||||
$unformattedText = undef;
|
||||
}
|
||||
elsif ($token =~ /^<\/pre>$/i)
|
||||
{
|
||||
if ($inCode && $unformattedText)
|
||||
{
|
||||
$unformattedText =~ s/^ {$sharedCodeIndent}//mg;
|
||||
$unformattedText =~ s/\n{3,}/\n\n/g;
|
||||
$unformattedText =~ s/\n+$//;
|
||||
$output .= '<code type="anonymous">' . $unformattedText . '</code>';
|
||||
|
||||
$sharedCodeIndent = undef;
|
||||
};
|
||||
|
||||
$inCode = 0;
|
||||
$unformattedText = undef;
|
||||
}
|
||||
elsif (length($token))
|
||||
{
|
||||
if (!$inCode)
|
||||
{
|
||||
$token =~ s/^ +//;
|
||||
if ($unformattedText)
|
||||
{ $unformattedText .= ' '; };
|
||||
}
|
||||
else
|
||||
{
|
||||
$token =~ /^( *)/;
|
||||
my $indent = length($1);
|
||||
|
||||
if (!defined $sharedCodeIndent || $indent < $sharedCodeIndent)
|
||||
{ $sharedCodeIndent = $indent; };
|
||||
};
|
||||
|
||||
$unformattedText .= $token;
|
||||
};
|
||||
};
|
||||
|
||||
if ($inCode && $unformattedText)
|
||||
{ $unformattedText .= "\n"; };
|
||||
|
||||
$i++;
|
||||
};
|
||||
|
||||
if ($unformattedText)
|
||||
{
|
||||
if ($inCode)
|
||||
{
|
||||
$unformattedText =~ s/^ {$sharedCodeIndent}//mg;
|
||||
$unformattedText =~ s/\n{3,}/\n\n/g;
|
||||
$unformattedText =~ s/\n+$//;
|
||||
$output .= '<code type="anonymous">' . $unformattedText . '</code>';
|
||||
}
|
||||
else
|
||||
{ $output .= '<p>' . $self->FormatText($unformattedText, 1) . '</p>'; };
|
||||
|
||||
$unformattedText = undef;
|
||||
};
|
||||
|
||||
|
||||
# Stage two: Block level tags.
|
||||
|
||||
my ($keyword, $value, $unformattedTextPtr, $unformattedTextCloser);
|
||||
my ($params, $authors, $deprecation, $throws, $returns, $seeAlso, $since, $version);
|
||||
|
||||
|
||||
while ($i < scalar @$commentLines)
|
||||
{
|
||||
my $line = $self->ConvertAmpChars($commentLines->[$i]);
|
||||
$line =~ s/^ +//;
|
||||
|
||||
if ($line =~ /^@([a-z]+) ?(.*)$/i)
|
||||
{
|
||||
($keyword, $value) = (lc($1), $2);
|
||||
|
||||
# Process the previous one, if any.
|
||||
if ($unformattedText)
|
||||
{
|
||||
$$unformattedTextPtr .= $self->FormatText($unformattedText) . $unformattedTextCloser;
|
||||
$unformattedText = undef;
|
||||
};
|
||||
|
||||
if ($keyword eq 'param')
|
||||
{
|
||||
$value =~ /^([a-z0-9_]+) *(.*)$/i;
|
||||
|
||||
$params .= '<de>' . $1 . '</de><dd>';
|
||||
$unformattedText = $2;
|
||||
|
||||
$unformattedTextPtr = \$params;
|
||||
$unformattedTextCloser = '</dd>';
|
||||
}
|
||||
elsif ($keyword eq 'exception' || $keyword eq 'throws')
|
||||
{
|
||||
$value =~ /^([a-z0-9_]+) *(.*)$/i;
|
||||
|
||||
$throws .= '<de>' . $1 . '</de><dd>';
|
||||
$unformattedText = $2;
|
||||
|
||||
$unformattedTextPtr = \$throws;
|
||||
$unformattedTextCloser = '</dd>';
|
||||
}
|
||||
elsif ($keyword eq 'return' || $keyword eq 'returns')
|
||||
{
|
||||
if ($returns)
|
||||
{ $returns .= ' '; };
|
||||
|
||||
$unformattedText = $value;
|
||||
$unformattedTextPtr = \$returns;
|
||||
$unformattedTextCloser = undef;
|
||||
}
|
||||
elsif ($keyword eq 'author')
|
||||
{
|
||||
if ($authors)
|
||||
{ $authors .= ', '; };
|
||||
|
||||
$unformattedText = $value;
|
||||
$unformattedTextPtr = \$authors;
|
||||
$unformattedTextCloser = undef;
|
||||
}
|
||||
elsif ($keyword eq 'deprecated')
|
||||
{
|
||||
if ($deprecation)
|
||||
{ $deprecation .= ' '; };
|
||||
|
||||
$unformattedText = $value;
|
||||
$unformattedTextPtr = \$deprecation;
|
||||
$unformattedTextCloser = undef;
|
||||
}
|
||||
elsif ($keyword eq 'since')
|
||||
{
|
||||
if ($since)
|
||||
{ $since .= ', '; };
|
||||
|
||||
$unformattedText = $value;
|
||||
$unformattedTextPtr = \$since;
|
||||
$unformattedTextCloser = undef;
|
||||
}
|
||||
elsif ($keyword eq 'version')
|
||||
{
|
||||
if ($version)
|
||||
{ $version .= ', '; };
|
||||
|
||||
$unformattedText = $value;
|
||||
$unformattedTextPtr = \$version;
|
||||
$unformattedTextCloser = undef;
|
||||
}
|
||||
elsif ($keyword eq 'see')
|
||||
{
|
||||
if ($seeAlso)
|
||||
{ $seeAlso .= ', '; };
|
||||
|
||||
$unformattedText = undef;
|
||||
|
||||
if ($value =~ /^&(?:quot|lt);/i)
|
||||
{ $seeAlso .= $self->FormatText($value); }
|
||||
else
|
||||
{ $seeAlso .= $self->ConvertLink($value); };
|
||||
};
|
||||
|
||||
# Everything else will be skipped.
|
||||
}
|
||||
elsif ($unformattedText)
|
||||
{
|
||||
$unformattedText .= ' ' . $line;
|
||||
};
|
||||
|
||||
$i++;
|
||||
};
|
||||
|
||||
if ($unformattedText)
|
||||
{
|
||||
$$unformattedTextPtr .= $self->FormatText($unformattedText) . $unformattedTextCloser;
|
||||
$unformattedText = undef;
|
||||
};
|
||||
|
||||
if ($params)
|
||||
{ $output .= '<h>Parameters</h><dl>' . $params . '</dl>'; };
|
||||
if ($returns)
|
||||
{ $output .= '<h>Returns</h><p>' . $returns . '</p>'; };
|
||||
if ($throws)
|
||||
{ $output .= '<h>Throws</h><dl>' . $throws . '</dl>'; };
|
||||
if ($since)
|
||||
{ $output .= '<h>Since</h><p>' . $since . '</p>'; };
|
||||
if ($version)
|
||||
{ $output .= '<h>Version</h><p>' . $version . '</p>'; };
|
||||
if ($deprecation)
|
||||
{ $output .= '<h>Deprecated</h><p>' . $deprecation . '</p>'; };
|
||||
if ($authors)
|
||||
{ $output .= '<h>Author</h><p>' . $authors . '</p>'; };
|
||||
if ($seeAlso)
|
||||
{ $output .= '<h>See Also</h><p>' . $seeAlso . '</p>'; };
|
||||
|
||||
|
||||
# Stage three: Build the parsed topic.
|
||||
|
||||
my $summary = NaturalDocs::Parser->GetSummaryFromBody($output);
|
||||
|
||||
push @$parsedTopics, NaturalDocs::Parser::ParsedTopic->New(undef, undef, undef, undef, undef, $summary,
|
||||
$output, $lineNumber, undef);
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
##
|
||||
# Translates any inline tags or HTML codes to <NDMarkup> and returns it.
|
||||
#
|
||||
sub FormatText #(string text, bool inParagraph)
|
||||
{
|
||||
my ($self, $text, $inParagraph) = @_;
|
||||
|
||||
# JavaDoc Literal
|
||||
|
||||
$text =~ s/\{\@(?:code|literal) ([^\}]*)\}/$self->ConvertAmpChars($1)/gie;
|
||||
|
||||
|
||||
# HTML
|
||||
|
||||
$text =~ s/<b>(.*?)<\/b>/<b>$1<\/b>/gi;
|
||||
$text =~ s/<i>(.*?)<\/i>/<i>$1<\/i>/gi;
|
||||
$text =~ s/<u>(.*?)<\/u>/<u>$1<\/u>/gi;
|
||||
|
||||
$text =~ s/<code>(.*?)<\/code>/$1/gi;
|
||||
|
||||
$text =~ s/<ul.*?>(.*?)<\/ul>/<ul>$1<\/ul>/gi;
|
||||
$text =~ s/<ol.*?>(.*?)<\/ol>/<ul>$1<\/ul>/gi;
|
||||
$text =~ s/<li.*?>(.*?)<\/li>/<li>$1<\/li>/gi;
|
||||
|
||||
$text =~ s/<!--.*?-->//gi;
|
||||
|
||||
$text =~ s/<\/p>//gi;
|
||||
$text =~ s/^<p>//i;
|
||||
if ($inParagraph)
|
||||
{ $text =~ s/<p>/<\/p><p>/gi; }
|
||||
else
|
||||
{ $text =~ s/<p>//gi; };
|
||||
|
||||
$text =~ s/<a href="mailto:(.*?)".*?>(.*?)<\/a>/$self->MakeEMailLink($1, $2)/gie;
|
||||
$text =~ s/<a href="(.*?)".*?>(.*?)<\/a>/$self->MakeURLLink($1, $2)/gie;
|
||||
|
||||
$text =~ s/&nbsp;/ /gi;
|
||||
$text =~ s/&amp;/&/gi;
|
||||
$text =~ s/&gt;/>/gi;
|
||||
$text =~ s/&lt;/</gi;
|
||||
$text =~ s/&quot;/"/gi;
|
||||
|
||||
|
||||
|
||||
# JavaDoc
|
||||
|
||||
$text =~ s/\{\@inheritdoc\}//gi;
|
||||
$text =~ s/\{\@(?:linkplain|link|value) ([^\}]*)\}/$self->ConvertLink($1)/gie;
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
|
||||
sub ConvertAmpChars #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$text =~ s/&/&/g;
|
||||
$text =~ s/</</g;
|
||||
$text =~ s/>/>/g;
|
||||
$text =~ s/"/"/g;
|
||||
|
||||
return $text;
|
||||
};
|
||||
|
||||
sub ConvertLink #(text)
|
||||
{
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$text =~ /^ *([a-z0-9\_\.\:\#]+(?:\([^\)]*\))?) *(.*)$/i;
|
||||
my ($target, $label) = ($1, $2);
|
||||
|
||||
# Convert the anchor to part of the link, but remove it altogether if it's the beginning of the link.
|
||||
$target =~ s/^\#//;
|
||||
$target =~ s/\#/\./;
|
||||
|
||||
$label =~ s/ +$//;
|
||||
|
||||
if (!length $label)
|
||||
{ return '<link target="' . $target . '" name="' . $target . '" original="' . $target . '">'; }
|
||||
else
|
||||
{ return '<link target="' . $target . '" name="' . $label . '" original="' . $label . ' (' . $target . ')">'; };
|
||||
};
|
||||
|
||||
sub MakeURLLink #(target, text)
|
||||
{
|
||||
my ($self, $target, $text) = @_;
|
||||
return '<url target="' . $target . '" name="' . $text . '">';
|
||||
};
|
||||
|
||||
sub MakeEMailLink #(target, text)
|
||||
{
|
||||
my ($self, $target, $text) = @_;
|
||||
return '<email target="' . $target . '" name="' . $text . '">';
|
||||
};
|
||||
|
||||
|
||||
1;
|
1073
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/Native.pm
Executable file
1073
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/Native.pm
Executable file
File diff suppressed because it is too large
Load Diff
254
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/ParsedTopic.pm
Executable file
254
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Parser/ParsedTopic.pm
Executable file
@ -0,0 +1,254 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Parser::ParsedTopic
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class for parsed topics of source files. Also encompasses some of the <TopicType>-specific behavior.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Parser::ParsedTopic;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The object is a blessed arrayref with the following indexes.
|
||||
#
|
||||
# TYPE - The <TopicType>.
|
||||
# TITLE - The title of the topic.
|
||||
# PACKAGE - The package <SymbolString> the topic appears in, or undef if none.
|
||||
# USING - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
|
||||
# none.
|
||||
# PROTOTYPE - The prototype, if it exists and is applicable.
|
||||
# SUMMARY - The summary, if it exists.
|
||||
# BODY - The body of the topic, formatted in <NDMarkup>. Some topics may not have bodies, and if not, this
|
||||
# will be undef.
|
||||
# LINE_NUMBER - The line number the topic appears at in the file.
|
||||
# IS_LIST - Whether the topic is a list.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'TYPE', 'TITLE', 'PACKAGE', 'USING', 'PROTOTYPE', 'SUMMARY', 'BODY',
|
||||
'LINE_NUMBER', 'IS_LIST';
|
||||
# DEPENDENCY: New() depends on the order of these constants, and that this class is not inheriting any members.
|
||||
|
||||
|
||||
#
|
||||
# Architecture: Title, Package, and Symbol Behavior
|
||||
#
|
||||
# Title, package, and symbol behavior is a little awkward so it deserves some explanation. Basically you set them according to
|
||||
# certain rules, but you get computed values that try to hide all the different scoping situations.
|
||||
#
|
||||
# Normal Topics:
|
||||
#
|
||||
# Set them to the title and package as they appear. "Function" and "PkgA.PkgB" will return "Function" for the title,
|
||||
# "PkgA.PkgB" for the package, and "PkgA.PkgB.Function" for the symbol.
|
||||
#
|
||||
# In the rare case that a title has a separator symbol it's treated as inadvertant, so "A vs. B" in "PkgA.PkgB" still returns just
|
||||
# "PkgA.PkgB" for the package even though if you got it from the symbol it can be seen as "PkgA.PkgB.A vs".
|
||||
#
|
||||
# Scope Topics:
|
||||
#
|
||||
# Set the title normally and leave the package undef. So "PkgA.PkgB" and undef will return "PkgA.PkgB" for the title as well
|
||||
# as for the package and symbol.
|
||||
#
|
||||
# The only time you should set the package is when you have full language support and they only documented the class with
|
||||
# a partial title. So if you documented "PkgA.PkgB" with just "PkgB", you want to set the package to "PkgA". This
|
||||
# will return "PkgB" as the title for presentation and will return "PkgA.PkgB" for the package and symbol, which is correct.
|
||||
#
|
||||
# Always Global Topics:
|
||||
#
|
||||
# Set the title and package normally, do not set the package to undef. So "Global" and "PkgA.PkgB" will return "Global" as
|
||||
# the title, "PkgA.PkgB" as the package, and "Global" as the symbol.
|
||||
#
|
||||
# Um, yeah...:
|
||||
#
|
||||
# So does this suck? Yes, yes it does. But the suckiness is centralized here instead of having to be handled everywhere these
|
||||
# issues come into play. Just realize there are a certain set of rules to follow when you *set* these variables, and the results
|
||||
# you see when you *get* them are computed rather than literal.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <TopicType>.
|
||||
# title - The title of the topic.
|
||||
# package - The package <SymbolString> the topic appears in, or undef if none.
|
||||
# using - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
|
||||
# none.
|
||||
# prototype - The prototype, if it exists and is applicable. Otherwise set to undef.
|
||||
# summary - The summary of the topic, if any.
|
||||
# body - The body of the topic, formatted in <NDMarkup>. May be undef, as some topics may not have bodies.
|
||||
# lineNumber - The line number the topic appears at in the file.
|
||||
# isList - Whether the topic is a list topic or not.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The new object.
|
||||
#
|
||||
sub New #(type, title, package, using, prototype, summary, body, lineNumber, isList)
|
||||
{
|
||||
# DEPENDENCY: This depends on the order of the parameter list being the same as the constants, and that there are no
|
||||
# members inherited from a base class.
|
||||
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
if (defined $object->[USING])
|
||||
{ $object->[USING] = [ @{$object->[USING]} ]; };
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Type
|
||||
# Returns the <TopicType>.
|
||||
sub Type
|
||||
{ return $_[0]->[TYPE]; };
|
||||
|
||||
# Function: SetType
|
||||
# Replaces the <TopicType>.
|
||||
sub SetType #(type)
|
||||
{ $_[0]->[TYPE] = $_[1]; };
|
||||
|
||||
# Function: IsList
|
||||
# Returns whether the topic is a list.
|
||||
sub IsList
|
||||
{ return $_[0]->[IS_LIST]; };
|
||||
|
||||
# Function: SetIsList
|
||||
# Sets whether the topic is a list.
|
||||
sub SetIsList
|
||||
{ $_[0]->[IS_LIST] = $_[1]; };
|
||||
|
||||
# Function: Title
|
||||
# Returns the title of the topic.
|
||||
sub Title
|
||||
{ return $_[0]->[TITLE]; };
|
||||
|
||||
# Function: SetTitle
|
||||
# Replaces the topic title.
|
||||
sub SetTitle #(title)
|
||||
{ $_[0]->[TITLE] = $_[1]; };
|
||||
|
||||
#
|
||||
# Function: Symbol
|
||||
#
|
||||
# Returns the <SymbolString> defined by the topic. It is fully resolved and does _not_ need to be joined with <Package()>.
|
||||
#
|
||||
# Type-Specific Behavior:
|
||||
#
|
||||
# - If the <TopicType> is always global, the symbol will be generated from the title only.
|
||||
# - Everything else's symbols will be generated from the title and the package passed to <New()>.
|
||||
#
|
||||
sub Symbol
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $titleSymbol = NaturalDocs::SymbolString->FromText($self->[TITLE]);
|
||||
|
||||
if (NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_ALWAYS_GLOBAL())
|
||||
{ return $titleSymbol; }
|
||||
else
|
||||
{
|
||||
return NaturalDocs::SymbolString->Join( $self->[PACKAGE], $titleSymbol );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Package
|
||||
#
|
||||
# Returns the package <SymbolString> that the topic appears in.
|
||||
#
|
||||
# Type-Specific Behavior:
|
||||
#
|
||||
# - If the <TopicType> has scope, the package will be generated from both the title and the package passed to <New()>, not
|
||||
# just the package.
|
||||
# - If the <TopicType> is always global, the package will be the one passed to <New()>, even though it isn't part of it's
|
||||
# <Symbol()>.
|
||||
# - Everything else's package will be what was passed to <New()>, even if the title has separator symbols in it.
|
||||
#
|
||||
sub Package
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
# Headerless topics may not have a type yet.
|
||||
if ($self->Type() && NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_START())
|
||||
{ return $self->Symbol(); }
|
||||
else
|
||||
{ return $self->[PACKAGE]; };
|
||||
};
|
||||
|
||||
|
||||
# Function: SetPackage
|
||||
# Replaces the package the topic appears in. This will behave the same way as the package parameter in <New()>. Later calls
|
||||
# to <Package()> will still be generated according to its type-specific behavior.
|
||||
sub SetPackage #(package)
|
||||
{ $_[0]->[PACKAGE] = $_[1]; };
|
||||
|
||||
# Function: Using
|
||||
# Returns an arrayref of additional scope <SymbolStrings> available to the topic via "using" statements, or undef if none.
|
||||
sub Using
|
||||
{ return $_[0]->[USING]; };
|
||||
|
||||
# Function: SetUsing
|
||||
# Replaces the using arrayref of sope <SymbolStrings>.
|
||||
sub SetUsing #(using)
|
||||
{ $_[0]->[USING] = $_[1]; };
|
||||
|
||||
# Function: Prototype
|
||||
# Returns the prototype if one is defined. Will be undef otherwise.
|
||||
sub Prototype
|
||||
{ return $_[0]->[PROTOTYPE]; };
|
||||
|
||||
# Function: SetPrototype
|
||||
# Replaces the function or variable prototype.
|
||||
sub SetPrototype #(prototype)
|
||||
{ $_[0]->[PROTOTYPE] = $_[1]; };
|
||||
|
||||
# Function: Summary
|
||||
# Returns the topic summary, if it exists, formatted in <NDMarkup>.
|
||||
sub Summary
|
||||
{ return $_[0]->[SUMMARY]; };
|
||||
|
||||
# Function: Body
|
||||
# Returns the topic's body, formatted in <NDMarkup>. May be undef.
|
||||
sub Body
|
||||
{ return $_[0]->[BODY]; };
|
||||
|
||||
# Function: SetBody
|
||||
# Replaces the topic's body, formatted in <NDMarkup>. May be undef.
|
||||
sub SetBody #(body)
|
||||
{
|
||||
my ($self, $body) = @_;
|
||||
$self->[BODY] = $body;
|
||||
};
|
||||
|
||||
# Function: LineNumber
|
||||
# Returns the line the topic appears at in the file.
|
||||
sub LineNumber
|
||||
{ return $_[0]->[LINE_NUMBER]; };
|
||||
|
||||
|
||||
1;
|
1406
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project.pm
Executable file
1406
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project.pm
Executable file
File diff suppressed because it is too large
Load Diff
161
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/ImageFile.pm
Executable file
161
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/ImageFile.pm
Executable file
@ -0,0 +1,161 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Project::ImageFile
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A simple information class about project image files.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Project::ImageFile;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are used as indexes.
|
||||
#
|
||||
# LAST_MODIFIED - The integer timestamp of when the file was last modified.
|
||||
# STATUS - <FileStatus> since the last build.
|
||||
# REFERENCE_COUNT - The number of references to the image from the source files.
|
||||
# WAS_USED - Whether the image was used the last time Natural Docs was run.
|
||||
# WIDTH - The image width. Undef if can't be determined, -1 if haven't attempted to determine yet.
|
||||
# HEIGHT - The image height. Undef if can't be determined, -1 if haven't attempted to determine yet.
|
||||
#
|
||||
|
||||
use NaturalDocs::DefineMembers 'LAST_MODIFIED', 'LastModified()', 'SetLastModified()',
|
||||
'STATUS', 'Status()', 'SetStatus()',
|
||||
'REFERENCE_COUNT', 'ReferenceCount()',
|
||||
'WAS_USED', 'WasUsed()', 'SetWasUsed()',
|
||||
'WIDTH', 'Width()',
|
||||
'HEIGHT', 'Height()';
|
||||
|
||||
|
||||
#
|
||||
# Topic: WasUsed versus References
|
||||
#
|
||||
# <WasUsed()> is a simple true/false that notes whether this image file was used the last time Natural Docs was run.
|
||||
# <ReferenceCount()> is a counter for the number of times it's used *this* run. As such, it starts at zero regardless of whether
|
||||
# <WasUsed()> is set or not.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new file object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# lastModified - The image file's last modification timestamp
|
||||
# status - The <FileStatus>.
|
||||
# wasUsed - Whether this image file was used the *last* time Natural Docs was run.
|
||||
#
|
||||
sub New #(timestamp lastModified, FileStatus status, bool wasUsed)
|
||||
{
|
||||
my ($package, $lastModified, $status, $width, $height, $wasUsed) = @_;
|
||||
|
||||
my $object = [ ];
|
||||
$object->[LAST_MODIFIED] = $lastModified;
|
||||
$object->[STATUS] = $status;
|
||||
$object->[REFERENCE_COUNT] = 0;
|
||||
$object->[WAS_USED] = $wasUsed;
|
||||
$object->[WIDTH] = -1;
|
||||
$object->[HEIGHT] = -1;
|
||||
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Member Functions
|
||||
#
|
||||
# LastModified - Returns the integer timestamp of when the file was last modified.
|
||||
# SetLastModified - Sets the file's last modification timestamp.
|
||||
# Status - Returns the <FileStatus> since the last build.
|
||||
# SetStatus - Sets the <FileStatus> since the last build.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: ReferenceCount
|
||||
# Returns the current number of references to this image file during *this* Natural Docs execution.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: AddReference
|
||||
# Increases the number of references to this image file by one. Returns the new reference count.
|
||||
#
|
||||
sub AddReference
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
$self->[REFERENCE_COUNT]++;
|
||||
return $self->[REFERENCE_COUNT];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: DeleteReference
|
||||
# Decreases the number of references to this image file by one. Returns the new reference count.
|
||||
#
|
||||
sub DeleteReference
|
||||
{
|
||||
my $self = shift;
|
||||
$self->[REFERENCE_COUNT]--;
|
||||
|
||||
if ($self->[REFERENCE_COUNT] < 0)
|
||||
{ die "Deleted more references to an image file than existed."; };
|
||||
|
||||
return $self->[REFERENCE_COUNT];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Member Functions
|
||||
#
|
||||
# WasUsed - Returns whether this image file was used during the *last* Natural Docs execution.
|
||||
# SetWasUsed - Sets whether this image file was used during the *last* Natural Docs execution.
|
||||
# Width - Returns the width in pixels, undef if it can't be determined, and -1 if determination hasn't been attempted yet.
|
||||
# Height - Returns the width in pixels, undef if it can't be determined, and -1 if determination hasn't been attempted yet.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: SetDimensions
|
||||
# Sets the width and height of the image. Set to undef if they can't be determined.
|
||||
#
|
||||
sub SetDimensions #(int width, int height)
|
||||
{
|
||||
my ($self, $width, $height) = @_;
|
||||
|
||||
# If either are undef, both should be undef. This will also convert zeroes to undef.
|
||||
if (!$width || !$height)
|
||||
{
|
||||
$self->[WIDTH] = undef;
|
||||
$self->[HEIGHT] = undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
$self->[WIDTH] = $width;
|
||||
$self->[HEIGHT] = $height;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
114
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/SourceFile.pm
Executable file
114
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Project/SourceFile.pm
Executable file
@ -0,0 +1,114 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Project::SourceFile
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A simple information class about project files.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Project::SourceFile;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are used as indexes.
|
||||
#
|
||||
# HAS_CONTENT - Whether the file contains Natural Docs content or not.
|
||||
# LAST_MODIFIED - The integer timestamp of when the file was last modified.
|
||||
# STATUS - <FileStatus> since the last build.
|
||||
# DEFAULT_MENU_TITLE - The file's default title in the menu.
|
||||
#
|
||||
|
||||
# DEPENDENCY: New() depends on its parameter list being in the same order as these constants. If the order changes, New()
|
||||
# needs to be changed.
|
||||
use NaturalDocs::DefineMembers 'HAS_CONTENT', 'LAST_MODIFIED', 'STATUS', 'DEFAULT_MENU_TITLE';
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new file object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# hasContent - Whether the file contains Natural Docs content or not.
|
||||
# lastModified - The integer timestamp of when the file was last modified.
|
||||
# status - The <FileStatus> since the last build.
|
||||
# defaultMenuTitle - The file's title in the menu.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# A reference to the new object.
|
||||
#
|
||||
sub New #(hasContent, lastModified, status, defaultMenuTitle)
|
||||
{
|
||||
# DEPENDENCY: This function depends on its parameter list being in the same order as the member constants. If either order
|
||||
# changes, this function needs to be changed.
|
||||
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
# Function: HasContent
|
||||
# Returns whether the file contains Natural Docs content or not.
|
||||
sub HasContent
|
||||
{ return $_[0]->[HAS_CONTENT]; };
|
||||
|
||||
# Function: SetHasContent
|
||||
# Sets whether the file contains Natural Docs content or not.
|
||||
sub SetHasContent #(hasContent)
|
||||
{ $_[0]->[HAS_CONTENT] = $_[1]; };
|
||||
|
||||
# Function: LastModified
|
||||
# Returns the integer timestamp of when the file was last modified.
|
||||
sub LastModified
|
||||
{ return $_[0]->[LAST_MODIFIED]; };
|
||||
|
||||
# Function: SetLastModified
|
||||
# Sets the file's last modification timestamp.
|
||||
sub SetLastModified #(lastModified)
|
||||
{ $_[0]->[LAST_MODIFIED] = $_[1]; };
|
||||
|
||||
# Function: Status
|
||||
# Returns the <FileStatus> since the last build.
|
||||
sub Status
|
||||
{ return $_[0]->[STATUS]; };
|
||||
|
||||
# Function: SetStatus
|
||||
# Sets the <FileStatus> since the last build.
|
||||
sub SetStatus #(status)
|
||||
{ $_[0]->[STATUS] = $_[1]; };
|
||||
|
||||
# Function: DefaultMenuTitle
|
||||
# Returns the file's default title on the menu.
|
||||
sub DefaultMenuTitle
|
||||
{ return $_[0]->[DEFAULT_MENU_TITLE]; };
|
||||
|
||||
# Function: SetDefaultMenuTitle
|
||||
# Sets the file's default title on the menu.
|
||||
sub SetDefaultMenuTitle #(menuTitle)
|
||||
{ $_[0]->[DEFAULT_MENU_TITLE] = $_[1]; };
|
||||
|
||||
|
||||
1;
|
345
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ReferenceString.pm
Executable file
345
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/ReferenceString.pm
Executable file
@ -0,0 +1,345 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::ReferenceString
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to manage <ReferenceString> handling throughout the program.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::ReferenceString;
|
||||
|
||||
use vars '@ISA', '@EXPORT';
|
||||
@ISA = 'Exporter';
|
||||
@EXPORT = ( 'BINARYREF_NOTYPE', 'BINARYREF_NORESOLVINGFLAGS',
|
||||
|
||||
'REFERENCE_TEXT', 'REFERENCE_CH_CLASS', 'REFERENCE_CH_PARENT',
|
||||
|
||||
'RESOLVE_RELATIVE', 'RESOLVE_ABSOLUTE', 'RESOLVE_NOPLURAL', 'RESOLVE_NOUSING' );
|
||||
|
||||
use Encode qw(encode_utf8 decode_utf8);
|
||||
|
||||
|
||||
#
|
||||
# Constants: Binary Format Flags
|
||||
#
|
||||
# These flags can be combined to specify the format when using <ToBinaryFile()> and <FromBinaryFile()>. All are exported
|
||||
# by default.
|
||||
#
|
||||
# BINARYREF_NOTYPE - Do not include the <ReferenceType>.
|
||||
# BINARYREF_NORESOLVEFLAGS - Do not include the <Resolving Flags>.
|
||||
#
|
||||
use constant BINARYREF_NOTYPE => 0x01;
|
||||
use constant BINARYREF_NORESOLVINGFLAGS => 0x02;
|
||||
|
||||
|
||||
#
|
||||
# Constants: ReferenceType
|
||||
#
|
||||
# The type of a reference.
|
||||
#
|
||||
# REFERENCE_TEXT - The reference appears in the text of the documentation.
|
||||
# REFERENCE_CH_CLASS - A class reference handled by <NaturalDocs::ClassHierarchy>.
|
||||
# REFERENCE_CH_PARENT - A parent class reference handled by <NaturalDocs::ClassHierarchy>.
|
||||
#
|
||||
# Dependencies:
|
||||
#
|
||||
# - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
|
||||
#
|
||||
use constant REFERENCE_TEXT => 1;
|
||||
use constant REFERENCE_CH_CLASS => 2;
|
||||
use constant REFERENCE_CH_PARENT => 3;
|
||||
|
||||
|
||||
#
|
||||
# Constants: Resolving Flags
|
||||
#
|
||||
# Used to influence the method of resolving references in <NaturalDocs::SymbolTable>.
|
||||
#
|
||||
# RESOLVE_RELATIVE - The reference text is truly relative, rather than Natural Docs' semi-relative.
|
||||
# RESOLVE_ABSOLUTE - The reference text is always absolute. No local or relative references.
|
||||
# RESOLVE_NOPLURAL - The reference text may not be interpreted as a plural, and thus match singular forms as well.
|
||||
# RESOLVE_NOUSING - The reference text may not include "using" statements when being resolved.
|
||||
#
|
||||
# If neither <RESOLVE_RELATIVE> or <RESOLVE_ABSOLUTE> is specified, Natural Docs' semi-relative kicks in instead,
|
||||
# which is where links are interpreted as local, then global, then relative. <RESOLVE_RELATIVE> states that links are
|
||||
# local, then relative, then global.
|
||||
#
|
||||
# Dependencies:
|
||||
#
|
||||
# - <ToBinaryFile()> and <FromBinaryFile()> require that these values fit into a UInt8, i.e. are <= 255.
|
||||
#
|
||||
use constant RESOLVE_RELATIVE => 0x01;
|
||||
use constant RESOLVE_ABSOLUTE => 0x02;
|
||||
use constant RESOLVE_NOPLURAL => 0x04;
|
||||
use constant RESOLVE_NOUSING => 0x08;
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# Function: MakeFrom
|
||||
#
|
||||
# Encodes the passed information as a <ReferenceString>. The format of the string should be treated as opaque. However, the
|
||||
# characteristic you can rely on is that the same string will always be made from the same parameters, and thus it's suitable
|
||||
# for comparison and use as hash keys.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The <ReferenceType>.
|
||||
# symbol - The <SymbolString> of the reference.
|
||||
# language - The name of the language that defines the file this reference appears in.
|
||||
# scope - The scope <SymbolString> the reference appears in, or undef if none.
|
||||
# using - An arrayref of scope <SymbolStrings> that are also available for checking due to the equivalent a "using" statement,
|
||||
# or undef if none.
|
||||
# resolvingFlags - The <Resolving Flags> to use with this reference. They are ignored if the type is <REFERENCE_TEXT>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The encoded <ReferenceString>.
|
||||
#
|
||||
sub MakeFrom #(ReferenceType type, SymbolString symbol, string language, SymbolString scope, SymbolString[]* using, flags resolvingFlags)
|
||||
{
|
||||
my ($self, $type, $symbol, $language, $scope, $using, $resolvingFlags) = @_;
|
||||
|
||||
if ($type == ::REFERENCE_TEXT() || $resolvingFlags == 0)
|
||||
{ $resolvingFlags = undef; };
|
||||
|
||||
# The format is [type] 0x1E [resolving flags] 0x1E [symbol] 0x1E [scope] ( 0x1E [using] )*
|
||||
# If there is no scope and/or using, the separator characters still remain.
|
||||
|
||||
# DEPENDENCY: SymbolString->FromText() removed all 0x1E characters.
|
||||
# DEPENDENCY: SymbolString->FromText() doesn't use 0x1E characters in its encoding.
|
||||
|
||||
my $string = $type . "\x1E" . $symbol . "\x1E" . $language . "\x1E" . $resolvingFlags . "\x1E";
|
||||
|
||||
if (defined $scope)
|
||||
{
|
||||
$string .= $scope;
|
||||
};
|
||||
|
||||
$string .= "\x1E";
|
||||
|
||||
if (defined $using)
|
||||
{
|
||||
$string .= join("\x1E", @$using);
|
||||
};
|
||||
|
||||
return $string;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToBinaryFile
|
||||
#
|
||||
# Writes a <ReferenceString> to the passed filehandle. Can also encode an undef.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The filehandle to write to.
|
||||
# referenceString - The <ReferenceString> to write, or undef.
|
||||
# binaryFormatFlags - Any <Binary Format Flags> you want to use to influence encoding.
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# > [SymbolString: Symbol or undef for an undef reference]
|
||||
# > [UString16: language]
|
||||
# > [SymbolString: Scope or undef for none]
|
||||
# >
|
||||
# > [SymbolString: Using or undef for none]
|
||||
# > [SymbolString: Using or undef for no more]
|
||||
# > ...
|
||||
# >
|
||||
# > [UInt8: Type unless BINARYREF_NOTYPE is set]
|
||||
# > [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
|
||||
#
|
||||
# Dependencies:
|
||||
#
|
||||
# - <ReferenceTypes> must fit into a UInt8. All values must be <= 255.
|
||||
# - All <Resolving Flags> must fit into a UInt8. All values must be <= 255.
|
||||
#
|
||||
sub ToBinaryFile #(FileHandle fileHandle, ReferenceString referenceString, flags binaryFormatFlags)
|
||||
{
|
||||
my ($self, $fileHandle, $referenceString, $binaryFormatFlags) = @_;
|
||||
|
||||
my ($type, $symbol, $language, $scope, $using, $resolvingFlags) = $self->InformationOf($referenceString);
|
||||
|
||||
# [SymbolString: Symbol or undef for an undef reference]
|
||||
|
||||
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $symbol);
|
||||
|
||||
# [UString16: language]
|
||||
|
||||
# $language may be undefined because $referenceString may be undefined to end a list of them.
|
||||
if (defined $language)
|
||||
{
|
||||
my $uLanguage = encode_utf8($language);
|
||||
print $fileHandle pack('na*', length $uLanguage, $uLanguage);
|
||||
}
|
||||
else
|
||||
{ print $fileHandle pack('n', 0); }
|
||||
|
||||
# [SymbolString: scope or undef if none]
|
||||
|
||||
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $scope);
|
||||
|
||||
# [SymbolString: using or undef if none/no more] ...
|
||||
|
||||
if (defined $using)
|
||||
{
|
||||
foreach my $usingScope (@$using)
|
||||
{ NaturalDocs::SymbolString->ToBinaryFile($fileHandle, $usingScope); };
|
||||
};
|
||||
|
||||
NaturalDocs::SymbolString->ToBinaryFile($fileHandle, undef);
|
||||
|
||||
# [UInt8: Type unless BINARYREF_NOTYPE is set]
|
||||
|
||||
if (!($binaryFormatFlags & BINARYREF_NOTYPE))
|
||||
{ print $fileHandle pack('C', $type); };
|
||||
|
||||
# [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
|
||||
|
||||
if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
|
||||
{ print $fileHandle pack('C', $type); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromBinaryFile
|
||||
#
|
||||
# Reads a <ReferenceString> or undef from the passed filehandle.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The filehandle to read from.
|
||||
# binaryFormatFlags - Any <Binary Format Flags> you want to use to influence decoding.
|
||||
# type - The <ReferenceType> to use if <BINARYREF_NOTYPE> is set.
|
||||
# resolvingFlags - The <Resolving Flags> to use if <BINARYREF_NORESOLVINGFLAGS> is set.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The <ReferenceString> or undef.
|
||||
#
|
||||
# See Also:
|
||||
#
|
||||
# See <ToBinaryFile()> for format and dependencies.
|
||||
#
|
||||
sub FromBinaryFile #(FileHandle fileHandle, flags binaryFormatFlags, ReferenceType type, flags resolvingFlags)
|
||||
{
|
||||
my ($self, $fileHandle, $binaryFormatFlags, $type, $resolvingFlags) = @_;
|
||||
my $raw;
|
||||
|
||||
# [SymbolString: Symbol or undef for an undef reference]
|
||||
|
||||
my $symbol = NaturalDocs::SymbolString->FromBinaryFile($fileHandle);
|
||||
|
||||
if (!defined $symbol)
|
||||
{ return undef; };
|
||||
|
||||
|
||||
# [UString16: language]
|
||||
|
||||
read($fileHandle, $raw, 2);
|
||||
my $languageLength = unpack('n', $raw);
|
||||
|
||||
my $language;
|
||||
read($fileHandle, $language, $languageLength);
|
||||
$language = decode_utf8($language);
|
||||
|
||||
|
||||
# [SymbolString: scope or undef if none]
|
||||
|
||||
my $scope = NaturalDocs::SymbolString->FromBinaryFile($fileHandle);
|
||||
|
||||
# [SymbolString: using or undef if none/no more] ...
|
||||
|
||||
my $usingSymbol;
|
||||
my @using;
|
||||
|
||||
while ($usingSymbol = NaturalDocs::SymbolString->FromBinaryFile($fileHandle))
|
||||
{ push @using, $usingSymbol; };
|
||||
|
||||
if (scalar @using)
|
||||
{ $usingSymbol = \@using; }
|
||||
else
|
||||
{ $usingSymbol = undef; };
|
||||
|
||||
# [UInt8: Type unless BINARYREF_NOTYPE is set]
|
||||
|
||||
if (!($binaryFormatFlags & BINARYREF_NOTYPE))
|
||||
{
|
||||
my $raw;
|
||||
read($fileHandle, $raw, 1);
|
||||
$type = unpack('C', $raw);
|
||||
};
|
||||
|
||||
# [UInt8: Resolving Flags unless BINARYREF_NORESOLVINGFLAGS is set]
|
||||
|
||||
if (!($binaryFormatFlags & BINARYREF_NORESOLVINGFLAGS))
|
||||
{
|
||||
my $raw;
|
||||
read($fileHandle, $raw, 1);
|
||||
$resolvingFlags = unpack('C', $raw);
|
||||
};
|
||||
|
||||
return $self->MakeFrom($type, $symbol, $language, $scope, $usingSymbol, $resolvingFlags);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: InformationOf
|
||||
#
|
||||
# Returns the information encoded in a <ReferenceString>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# referenceString - The <ReferenceString> to decode.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The array ( type, symbol, language, scope, using, resolvingFlags ).
|
||||
#
|
||||
# type - The <ReferenceType>.
|
||||
# symbol - The <SymbolString>.
|
||||
# language - The name of the language that defined the file the reference was defined in.
|
||||
# scope - The scope <SymbolString>, or undef if none.
|
||||
# using - An arrayref of scope <SymbolStrings> that the reference also has access to via "using" statements, or undef if none.
|
||||
# resolvingFlags - The <Resolving Flags> of the reference.
|
||||
#
|
||||
sub InformationOf #(ReferenceString referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
|
||||
my ($type, $symbolString, $language, $resolvingFlags, $scopeString, @usingStrings) = split(/\x1E/, $referenceString);
|
||||
|
||||
if (!length $resolvingFlags)
|
||||
{ $resolvingFlags = undef; };
|
||||
|
||||
return ( $type, $symbolString, $language, $scopeString, [ @usingStrings ], $resolvingFlags );
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: TypeOf
|
||||
#
|
||||
# Returns the <ReferenceType> encoded in the reference string. This is faster than <InformationOf()> if this is
|
||||
# the only information you need.
|
||||
#
|
||||
sub TypeOf #(ReferenceString referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
|
||||
$referenceString =~ /^([^\x1E]+)/;
|
||||
return $1;
|
||||
};
|
||||
|
||||
|
||||
1;
|
1484
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Settings.pm
Executable file
1484
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Settings.pm
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::Settings::BuildTarget
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class that stores information about a build target.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Settings::BuildTarget;
|
||||
|
||||
use NaturalDocs::DefineMembers 'BUILDER', 'Builder()', 'SetBuilder()',
|
||||
'DIRECTORY', 'Directory()', 'SetDirectory()';
|
||||
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref with the members below.
|
||||
#
|
||||
# BUILDER - The <NaturalDocs::Builder::Base>-derived object for the target's output format.
|
||||
# DIRECTORY - The output directory of the target.
|
||||
#
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# builder - The <NaturalDocs::Builder::Base>-derived object for the target's output format.
|
||||
# directory - The directory to place the output files in.
|
||||
#
|
||||
sub New #(builder, directory)
|
||||
{
|
||||
my ($package, $builder, $directory) = @_;
|
||||
|
||||
my $object = [ ];
|
||||
bless $object, $package;
|
||||
|
||||
$object->SetBuilder($builder);
|
||||
$object->SetDirectory($directory);
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Member Functions
|
||||
#
|
||||
# Builder - Returns the <NaturalDocs::Builder::Base>-derived object for the target's output format.
|
||||
# SetBuilder - Replaces the <NaturalDocs::Builder::Base>-derived object for the target's output format.
|
||||
# Directory - Returns the directory for the target's output files.
|
||||
# SetDirectory - Replaces the directory for the target's output files.
|
||||
#
|
||||
|
||||
|
||||
1;
|
679
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB.pm
Executable file
679
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB.pm
Executable file
@ -0,0 +1,679 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# SourceDB is an experimental package meant to unify the tracking of various elements in the source code.
|
||||
#
|
||||
# Requirements:
|
||||
#
|
||||
# - All extension packages must call <RegisterExtension()> before they can be used.
|
||||
#
|
||||
#
|
||||
# Architecture: The Idea
|
||||
#
|
||||
# For quite a while Natural Docs only needed <SymbolTable>. However, 1.3 introduced the <ClassHierarchy> package
|
||||
# which duplicated some of its functionality to track classes and parent references. 1.4 now needs <ImageReferenceTable>,
|
||||
# so this package was an attempt to isolate the common functionality so the wheel doesn't have to keep being rewritten as
|
||||
# the scope of Natural Docs expands.
|
||||
#
|
||||
# SourceDB is designed around <Extensions> and items. The purposefully vague "items" are anything in the source code
|
||||
# that we need to track the definitions of. Extensions are the packages to track them, only they're derived from
|
||||
# <NaturalDocs::SourceDB::Extension> and registered with this package instead of being free standing and duplicating
|
||||
# functionality such as watched files.
|
||||
#
|
||||
# The architecture on this package isn't comprehensive yet. As more extensions are added or previously made free standing
|
||||
# packages are migrated to it it will expand to encompass them. However, it's still experimental so this concept may
|
||||
# eventually be abandoned for something better instead.
|
||||
#
|
||||
#
|
||||
# Architecture: Assumptions
|
||||
#
|
||||
# SourceDB is built around certain assumptions.
|
||||
#
|
||||
# One item per file:
|
||||
#
|
||||
# SourceDB assumes that only the first item per file with a particular item string is relevant. For example, if two functions
|
||||
# have the exact same name, there's no way to link to the second one either in HTML or internally so it doesn't matter for
|
||||
# our purposes. Likewise, if two references are exactly the same they go to the same target, so it doesn't matter whether
|
||||
# there's one or two or a thousand. All that matters is that at least one reference exists in this file because you only need
|
||||
# to determine whether the entire file gets rebuilt. If two items are different in some meaningful way, they should generate
|
||||
# different item strings.
|
||||
#
|
||||
# Watched file parsing:
|
||||
#
|
||||
# SourceDB assumes the parse method is that the information that was stored from Natural Docs' previous run is loaded, a
|
||||
# file is watched, that file is reparsed, and then <AnalyzeWatchedFileChanges()> is called. When the file is reparsed all
|
||||
# items within it are added the same as if the file was never parsed before.
|
||||
#
|
||||
# If there's a new item this time around, that's fine no matter what. However, a changed item wouldn't normally be
|
||||
# recorded because the previous run's definition is seen as the first one and subsequent ones are ignored. Also, deleted
|
||||
# items would normally not be recorded either because we're only adding.
|
||||
#
|
||||
# The watched file method fixes this because everything is also added to a second, clean database specifically for the
|
||||
# watched file. Because it starts clean, it always gets the first definition from the current parse which can then be
|
||||
# compared to the original by <AnalyzeWatchedFileChanges()>. Because it starts clean you can also compare it to the
|
||||
# main database to see if anything was deleted, because it would appear in the main database but not the watched one.
|
||||
#
|
||||
# This means that functions like <ChangeDefinition()> and <DeleteDefinition()> should only be called by
|
||||
# <AnalyzeWatchedFileChanges()>. Externally only <AddDefinition()> should be called. <DeleteItem()> is okay to be
|
||||
# called externally because entire items aren't managed by the watched file database, only definitions.
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
use NaturalDocs::SourceDB::Extension;
|
||||
use NaturalDocs::SourceDB::Item;
|
||||
use NaturalDocs::SourceDB::ItemDefinition;
|
||||
use NaturalDocs::SourceDB::File;
|
||||
use NaturalDocs::SourceDB::WatchedFileDefinitions;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Types
|
||||
|
||||
|
||||
#
|
||||
# Type: ExtensionID
|
||||
#
|
||||
# A unique identifier for each <NaturalDocs::SourceDB> extension as given out by <RegisterExtension()>.
|
||||
#
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Variables
|
||||
|
||||
|
||||
#
|
||||
# array: extensions
|
||||
#
|
||||
# An array of <NaturalDocs::SourceDB::Extension>-derived extensions, as added with <RegisterExtension()>. The indexes
|
||||
# are the <ExtensionIDs> and the values are package references.
|
||||
#
|
||||
my @extensions;
|
||||
|
||||
#
|
||||
# array: extensionUsesDefinitionObjects
|
||||
#
|
||||
# An array where the indexes are <ExtensionIDs> and the values are whether that extension uses its own definition class
|
||||
# derived from <NaturalDocs::SourceDB::ItemDefinition> or it just tracks their existence.
|
||||
#
|
||||
my @extensionUsesDefinitionObjects;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# array: items
|
||||
#
|
||||
# The array of source items. The <ExtensionIDs> are the indexes, and the values are hashrefs mapping the item
|
||||
# string to <NaturalDocs::SourceDB::Item>-derived objects. Hashrefs may be undef.
|
||||
#
|
||||
my @items;
|
||||
|
||||
|
||||
#
|
||||
# hash: files
|
||||
#
|
||||
# A hashref mapping source <FileNames> to <NaturalDocs::SourceDB::Files>.
|
||||
#
|
||||
my %files;
|
||||
|
||||
|
||||
#
|
||||
# object: watchedFile
|
||||
#
|
||||
# When a file is being watched for changes, will be a <NaturalDocs::SourceDB::File> for that file. Is undef otherwise.
|
||||
#
|
||||
# When the file is parsed, items are added to both this and the version in <files>. Thus afterwards we can compare the two to
|
||||
# see if any were deleted since the last time Natural Docs was run, because they would be in the <files> version but not this
|
||||
# one.
|
||||
#
|
||||
my $watchedFile;
|
||||
|
||||
|
||||
#
|
||||
# string: watchedFileName
|
||||
#
|
||||
# When a file is being watched for changes, will be the <FileName> of the file being watched. Is undef otherwise.
|
||||
#
|
||||
my $watchedFileName;
|
||||
|
||||
|
||||
#
|
||||
# object: watchedFileDefinitions
|
||||
#
|
||||
# When a file is being watched for changes, will be a <NaturalDocs::SourceDB::WatchedFileDefinitions> object. Is undef
|
||||
# otherwise.
|
||||
#
|
||||
# When the file is parsed, items are added to both this and the version in <items>. Since only the first definition is kept, this
|
||||
# will always have the definition info from the file whereas the version in <items> will have the first definition as of the last time
|
||||
# Natural Docs was run. Thus they can be compared to see if the definitions of items that existed the last time around have
|
||||
# changed.
|
||||
#
|
||||
my $watchedFileDefinitions;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Extension Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: RegisterExtension
|
||||
#
|
||||
# Registers a <NaturalDocs::SourceDB::Extension>-derived package and returns a unique <ExtensionID> for it. All extensions
|
||||
# must call this before they can be used.
|
||||
#
|
||||
# Registration Order:
|
||||
#
|
||||
# The order in which extensions register is important. Whenever possible, items are added in the order their extensions
|
||||
# registered. However, items are changed and deleted in the reverse order. Take advantage of this to minimize
|
||||
# churn between extensions that are dependent on each other.
|
||||
#
|
||||
# For example, when symbols are added or deleted they may cause references to be retargeted and thus their files need to
|
||||
# be rebuilt. However, adding or deleting references never causes the symbols' files to be rebuilt. So it makes sense that
|
||||
# symbols should be created before references, and that references should be deleted before symbols.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - The package or object of the extension. Must be derived from <NaturalDocs::SourceDB::Extension>.
|
||||
# usesDefinitionObjects - Whether the extension uses its own class derived from <NaturalDocs::SourceDB::ItemDefinition>
|
||||
# or simply tracks each definitions existence.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# An <ExtensionID> unique to the extension. This should be saved because it's required in functions such as <AddItem()>.
|
||||
#
|
||||
sub RegisterExtension #(package extension, bool usesDefinitionObjects) => ExtensionID
|
||||
{
|
||||
my ($self, $extension, $usesDefinitionObjects) = @_;
|
||||
|
||||
push @extensions, $extension;
|
||||
push @extensionUsesDefinitionObjects, $usesDefinitionObjects;
|
||||
|
||||
return scalar @extensions - 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: File Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Load
|
||||
#
|
||||
# Loads the data of the source database and all the extensions. Will call <NaturalDocs::SourceDB::Extension->Load()> for
|
||||
# all of them, unless there's a situation where all the source files are going to be reparsed anyway in which case it's not needed.
|
||||
#
|
||||
sub Load
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
# No point loading if RebuildData is set.
|
||||
if (!NaturalDocs::Settings->RebuildData())
|
||||
{
|
||||
# If any load fails, stop loading the rest and just reparse all the source files.
|
||||
my $success = 1;
|
||||
|
||||
for (my $extension = 0; $extension < scalar @extensions && $success; $extension++)
|
||||
{
|
||||
$success = $extensions[$extension]->Load();
|
||||
};
|
||||
|
||||
if (!$success)
|
||||
{ NaturalDocs::Project->ReparseEverything(); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Save
|
||||
#
|
||||
# Saves the data of the source database and all its extensions. Will call <NaturalDocs::SourceDB::Extension->Save()> for all
|
||||
# of them.
|
||||
#
|
||||
sub Save
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
|
||||
{
|
||||
$extensions[$extension]->Save();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PurgeDeletedSourceFiles
|
||||
#
|
||||
# Removes all data associated with deleted source files.
|
||||
#
|
||||
sub PurgeDeletedSourceFiles
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $filesToPurge = NaturalDocs::Project->FilesToPurge();
|
||||
|
||||
# Extension is the outermost loop because we want the extensions added last to have their definitions removed first to cause
|
||||
# the least amount of churn between interdependent extensions.
|
||||
for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
|
||||
{
|
||||
foreach my $file (keys %$filesToPurge)
|
||||
{
|
||||
if (exists $files{$file})
|
||||
{
|
||||
my @items = $files{$file}->ListItems($extension);
|
||||
|
||||
foreach my $item (@items)
|
||||
{
|
||||
$self->DeleteDefinition($extension, $item, $file);
|
||||
};
|
||||
}; # file exists
|
||||
}; # each file
|
||||
}; # each extension
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Item Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: AddItem
|
||||
#
|
||||
# Adds the passed item to the database. This will not work if the item string already exists. The item added should *not*
|
||||
# already have definitions attached. Only use this to add blank items and then call <AddDefinition()> instead.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - An <ExtensionID>.
|
||||
# itemString - The string serving as the item identifier.
|
||||
# item - An object derived from <NaturalDocs::SourceDB::Item>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the item was added, that is, whether it was the first time this item was added.
|
||||
#
|
||||
sub AddItem #(ExtensionID extension, string itemString, NaturalDocs::SourceDB::Item item) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $item) = @_;
|
||||
|
||||
if (!defined $items[$extension])
|
||||
{ $items[$extension] = { }; };
|
||||
|
||||
if (!exists $items[$extension]->{$itemString})
|
||||
{
|
||||
if ($item->HasDefinitions())
|
||||
{ die "Tried to add an item to SourceDB that already had definitions."; };
|
||||
|
||||
$items[$extension]->{$itemString} = $item;
|
||||
return 1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetItem
|
||||
#
|
||||
# Returns the <NaturalDocs::SourceDB::Item>-derived object for the passed <ExtensionID> and item string, or undef if there
|
||||
# is none.
|
||||
#
|
||||
sub GetItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extensionID, $itemString) = @_;
|
||||
|
||||
if (defined $items[$extensionID])
|
||||
{ return $items[$extensionID]->{$itemString}; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteItem
|
||||
#
|
||||
# Deletes the record of the passed <ExtensionID> and item string. Do *not* delete items that still have definitions. Use
|
||||
# <DeleteDefinition()> first.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - The <ExtensionID>.
|
||||
# itemString - The item's identifying string.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether it was successful, meaning whether an entry existed for it.
|
||||
#
|
||||
sub DeleteItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $items[$extension] && exists $items[$extension]->{$itemString})
|
||||
{
|
||||
if ($items[$extension]->{$itemString}->HasDefinitions())
|
||||
{ die "Tried to delete an item from SourceDB that still has definitions."; };
|
||||
|
||||
delete $items[$extension]->{$itemString};
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasItem
|
||||
#
|
||||
# Returns whether there is an item defined for the passed <ExtensionID> and item string.
|
||||
#
|
||||
sub HasItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $items[$extension])
|
||||
{ return (exists $items[$extension]->{$itemString}); }
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetAllItemsHashRef
|
||||
#
|
||||
# Returns a hashref of all the items defined for an extension. *Do not change the contents.* The keys are the item strings and
|
||||
# the values are <NaturalDocs::SourceDB::Items> or derived classes.
|
||||
#
|
||||
sub GetAllItemsHashRef #(ExtensionID extension) => hashref
|
||||
{
|
||||
my ($self, $extension) = @_;
|
||||
return $items[$extension];
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Definition Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a definition to an item. Assumes the item was already created with <AddItem()>. If there's already a definition for this
|
||||
# file in the item, the new definition will be ignored.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - The <ExtensionID>.
|
||||
# itemString - The item string.
|
||||
# file - The <FileName> the definition is in.
|
||||
# definition - If you're using a custom <NaturalDocs::SourceDB::ItemDefinition> class, you must include an object for it here.
|
||||
# Otherwise this parameter is ignored.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
|
||||
#
|
||||
sub AddDefinition #(ExtensionID extension, string itemString, FileName file, optional NaturalDocs::SourceDB::ItemDefinition definition) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $file, $definition) = @_;
|
||||
|
||||
|
||||
# Items
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ die "Tried to add a definition to an undefined item in SourceDB."; };
|
||||
|
||||
if (!$extensionUsesDefinitionObjects[$extension])
|
||||
{ $definition = 1; };
|
||||
|
||||
my $result = $item->AddDefinition($file, $definition);
|
||||
|
||||
|
||||
# Files
|
||||
|
||||
if (!exists $files{$file})
|
||||
{ $files{$file} = NaturalDocs::SourceDB::File->New(); };
|
||||
|
||||
$files{$file}->AddItem($extension, $itemString);
|
||||
|
||||
|
||||
# Watched File
|
||||
|
||||
if ($self->WatchingFileForChanges())
|
||||
{
|
||||
$watchedFile->AddItem($extension, $itemString);
|
||||
|
||||
if ($extensionUsesDefinitionObjects[$extension])
|
||||
{ $watchedFileDefinitions->AddDefinition($extension, $itemString, $definition); };
|
||||
};
|
||||
|
||||
|
||||
return $result;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ChangeDefinition
|
||||
#
|
||||
# Changes the definition of an item. This function is only used for extensions that use custom
|
||||
# <NaturalDocs::SourceDB::ItemDefinition>-derived classes.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - The <ExtensionID>.
|
||||
# itemString - The item string.
|
||||
# file - The <FileName> the definition is in.
|
||||
# definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
|
||||
#
|
||||
sub ChangeDefinition #(ExtensionID extension, string itemString, FileName file, NaturalDocs::SourceDB::ItemDefinition definition)
|
||||
{
|
||||
my ($self, $extension, $itemString, $file, $definition) = @_;
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ die "Tried to change the definition of an undefined item in SourceDB."; };
|
||||
|
||||
if (!$extensionUsesDefinitionObjects[$extension])
|
||||
{ die "Tried to change the definition of an item in an extension that doesn't use definition objects in SourceDB."; };
|
||||
|
||||
if (!$item->HasDefinition($file))
|
||||
{ die "Tried to change a definition that doesn't exist in SourceDB."; };
|
||||
|
||||
$item->ChangeDefinition($file, $definition);
|
||||
$extensions[$extension]->OnChangedDefinition($itemString, $file);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetDefinition
|
||||
#
|
||||
# If the extension uses custom <NaturalDocs::SourceDB::ItemDefinition> classes, returns it for the passed definition or undef
|
||||
# if it doesn't exist. Otherwise returns whether it exists.
|
||||
#
|
||||
sub GetDefinition #(ExtensionID extension, string itemString, FileName file) => NaturalDocs::SourceDB::ItemDefinition or bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $file) = @_;
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ return undef; };
|
||||
|
||||
return $item->GetDefinition($file);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes the definition for the passed item. Returns whether it was successful, meaning whether a definition existed for that
|
||||
# file.
|
||||
#
|
||||
sub DeleteDefinition #(ExtensionID extension, string itemString, FileName file) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $file) = @_;
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ return 0; };
|
||||
|
||||
my $result = $item->DeleteDefinition($file);
|
||||
|
||||
if ($result)
|
||||
{
|
||||
$files{$file}->DeleteItem($extension, $itemString);
|
||||
$extensions[$extension]->OnDeletedDefinition($itemString, $file, !$item->HasDefinitions());
|
||||
};
|
||||
|
||||
return $result;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinitions
|
||||
#
|
||||
# Returns whether there are any definitions for this item.
|
||||
#
|
||||
sub HasDefinitions #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ return 0; };
|
||||
|
||||
return $item->HasDefinitions();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinition
|
||||
#
|
||||
# Returns whether there is a definition for the passed <FileName>.
|
||||
#
|
||||
sub HasDefinition #(ExtensionID extension, string itemString, FileName file) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $file) = @_;
|
||||
|
||||
my $item = $self->GetItem($extension, $itemString);
|
||||
|
||||
if (!defined $item)
|
||||
{ return 0; };
|
||||
|
||||
return $item->HasDefinition($file);
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Watched File Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: WatchFileForChanges
|
||||
#
|
||||
# Begins watching a file for changes. Only one file at a time can be watched.
|
||||
#
|
||||
# This should be called before a file is parsed so the file info goes both into the main database and the watched file info.
|
||||
# Afterwards you call <AnalyzeWatchedFileChanges()> so item deletions and definition changes can be detected.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# filename - The <FileName> to watch.
|
||||
#
|
||||
sub WatchFileForChanges #(FileName filename)
|
||||
{
|
||||
my ($self, $filename) = @_;
|
||||
|
||||
$watchedFileName = $filename;
|
||||
$watchedFile = NaturalDocs::SourceDB::File->New();
|
||||
$watchedFileDefinitions = NaturalDocs::SourceDB::WatchedFileDefinitions->New();
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: WatchingFileForChanges
|
||||
#
|
||||
# Returns whether we're currently watching a file for changes or not.
|
||||
#
|
||||
sub WatchingFileForChanges # => bool
|
||||
{
|
||||
my $self = shift;
|
||||
return defined $watchedFileName;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AnalyzeWatchedFileChanges
|
||||
#
|
||||
# Analyzes the watched file for changes. Will delete and change definitions as necessary.
|
||||
#
|
||||
sub AnalyzeWatchedFileChanges
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (!$self->WatchingFileForChanges())
|
||||
{ die "Tried to analyze watched file for changes in SourceDB when no file was being watched."; };
|
||||
if (!$files{$watchedFileName})
|
||||
{ return; };
|
||||
|
||||
|
||||
# Process extensions last registered to first.
|
||||
|
||||
for (my $extension = scalar @extensions - 1; $extension >= 0; $extension--)
|
||||
{
|
||||
my @items = $files{$watchedFileName}->ListItems($extension);
|
||||
|
||||
foreach my $item (@items)
|
||||
{
|
||||
if ($watchedFile->HasItem($extension, $item))
|
||||
{
|
||||
if ($extensionUsesDefinitionObjects[$extension])
|
||||
{
|
||||
my $originalDefinition = $items[$extension]->GetDefinition($watchedFileName);
|
||||
my $watchedDefinition = $watchedFileDefinitions->GetDefinition($extension, $item);
|
||||
|
||||
if (!$originalDefinition->Compare($watchedDefinition))
|
||||
{ $self->ChangeDefinition($extension, $item, $watchedFileName, $watchedDefinition); };
|
||||
}
|
||||
}
|
||||
else # !$watchedFile->HasItem($item)
|
||||
{
|
||||
$self->DeleteDefinition($extension, $item, $watchedFileName);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
$watchedFile = undef;
|
||||
$watchedFileName = undef;
|
||||
$watchedFileDefinitions = undef;
|
||||
};
|
||||
|
||||
|
||||
1;
|
85
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Extension.pm
Executable file
85
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Extension.pm
Executable file
@ -0,0 +1,85 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB::Extension
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A base package for all <SourceDB> extensions.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB::Extension;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Interface Functions
|
||||
# These functions must be overridden by the derived class.
|
||||
|
||||
|
||||
#
|
||||
# Function: Register
|
||||
#
|
||||
# Override this function to register the package with <NaturalDocs::SourceDB->RegisterExtension()>.
|
||||
#
|
||||
sub Register
|
||||
{
|
||||
die "Called SourceDB::Extension->Register(). This function should be overridden by every extension.";
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Load
|
||||
#
|
||||
# Called by <NaturalDocs::SourceDB->Load()> to load the extension's data. Returns whether it was successful.
|
||||
#
|
||||
# *This function might not be called.* If there's a situation that would cause all the source files to be reparsed anyway,
|
||||
# <NaturalDocs::SourceDB> may skip calling Load() for the remaining extensions. You should *not* depend on this function
|
||||
# for any critical initialization that needs to happen every time regardless.
|
||||
#
|
||||
sub Load # => bool
|
||||
{
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Save
|
||||
#
|
||||
# Called by <NaturalDocs::SourceDB->Save()> to save the extension's data.
|
||||
#
|
||||
sub Save
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnDeletedDefinition
|
||||
#
|
||||
# Called for each definition deleted by <NaturalDocs::SourceDB>. This is called *after* the definition has been deleted from
|
||||
# the database, so don't expect to be able to read it.
|
||||
#
|
||||
sub OnDeletedDefinition #(string itemString, FileName file, bool wasLastDefinition)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: OnChangedDefinition
|
||||
#
|
||||
# Called for each definition changed by <NaturalDocs::SourceDB>. This is called *after* the definition has been changed, so
|
||||
# don't expect to be able to read the original value.
|
||||
#
|
||||
sub OnChangedDefinition #(string itemString, FileName file)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
1;
|
130
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/File.pm
Executable file
130
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/File.pm
Executable file
@ -0,0 +1,130 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB::File
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class used to index items by file.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB::File;
|
||||
|
||||
use NaturalDocs::DefineMembers 'ITEMS';
|
||||
|
||||
|
||||
#
|
||||
# Variables: Members
|
||||
#
|
||||
# These constants serve as indexes into the object array.
|
||||
#
|
||||
# ITEMS - An arrayref where an <ExtensionID> is the index and the members are existence hashrefs of the item strigs defined
|
||||
# in this file. The arrayref will always exist, but the hashrefs may be undef.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ ];
|
||||
$object->[ITEMS] = [ ];
|
||||
|
||||
bless $object, $package;
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddItem
|
||||
#
|
||||
# Adds an item to this file. Returns whether this added a new item.
|
||||
#
|
||||
sub AddItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (!defined $self->[ITEMS]->[$extension])
|
||||
{
|
||||
$self->[ITEMS]->[$extension] = { $itemString => 1 };
|
||||
return 1;
|
||||
}
|
||||
elsif (!exists $self->[ITEMS]->[$extension]->{$itemString})
|
||||
{
|
||||
$self->[ITEMS]->[$extension]->{$itemString} = 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasItem
|
||||
#
|
||||
# Returns whether the item exists in this file.
|
||||
#
|
||||
sub HasItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $self->[ITEMS]->[$extension])
|
||||
{ return exists $self->[ITEMS]->[$extension]->{$itemString}; }
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteItem
|
||||
#
|
||||
# Deletes the passed item. Returns whether it existed.
|
||||
#
|
||||
sub DeleteItem #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (!defined $self->[ITEMS]->[$extension])
|
||||
{ return 0; }
|
||||
elsif (exists $self->[ITEMS]->[$extension]->{$itemString})
|
||||
{
|
||||
delete $self->[ITEMS]->[$extension]->{$itemString};
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ListItems
|
||||
#
|
||||
# Returns an array of all the item strings defined for a particular extension, or an empty list if none.
|
||||
#
|
||||
sub ListItems #(ExtensionID extension) => string array
|
||||
{
|
||||
my ($self, $extension) = @_;
|
||||
|
||||
if (defined $self->[ITEMS]->[$extension])
|
||||
{ return keys %{$self->[ITEMS]->[$extension]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
|
||||
1;
|
202
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Item.pm
Executable file
202
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SourceDB/Item.pm
Executable file
@ -0,0 +1,202 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB::Item
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A base class for something being tracked in <NaturalDocs::SourceDB>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB::Item;
|
||||
|
||||
use NaturalDocs::DefineMembers 'DEFINITIONS';
|
||||
|
||||
|
||||
#
|
||||
# Variables: Members
|
||||
#
|
||||
# The following constants are indexes into the object array.
|
||||
#
|
||||
# DEFINITIONS - A hashref that maps <FileNames> to either <NaturalDocs::SourceDB::ItemDefinition>-derived objects or
|
||||
# serves as an existence hashref depending on whether the extension only tracks existence. Will be undef if
|
||||
# there are none.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $class = shift;
|
||||
|
||||
my $object = [ ];
|
||||
bless $object, $class;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Group: Definition Functions
|
||||
#
|
||||
# These functions should be called by <NaturalDocs::SourceDB>. You should not be calling them directly. Call functions
|
||||
# like <NaturalDocs::SourceDB->AddDefinition()> instead.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a definition for the passed <FileName>. If it's already defined, the new definition will be ignored.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName>.
|
||||
# definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition> or undef if
|
||||
# the extension only tracks existence.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
|
||||
#
|
||||
sub AddDefinition #(FileName file, optional NaturalDocs::SourceDB::ItemDefinition definition) => bool
|
||||
{
|
||||
my ($self, $file, $definition) = @_;
|
||||
|
||||
if (!defined $self->[DEFINITIONS])
|
||||
{ $self->[DEFINITIONS] = { }; };
|
||||
|
||||
if (!exists $self->[DEFINITIONS]->{$file})
|
||||
{
|
||||
if (!defined $definition)
|
||||
{ $definition = 1; };
|
||||
|
||||
$self->[DEFINITIONS]->{$file} = $definition;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ChangeDefinition
|
||||
#
|
||||
# Changes the definition for the passed <FileName>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName>.
|
||||
# definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
|
||||
#
|
||||
sub ChangeDefinition #(FileName file, NaturalDocs::SourceDB::ItemDefinition definition)
|
||||
{
|
||||
my ($self, $file, $definition) = @_;
|
||||
|
||||
if (!defined $self->[DEFINITIONS] || !exists $self->[DEFINITIONS]->{$file})
|
||||
{ die "Tried to change a non-existant definition in SourceD::Item."; };
|
||||
|
||||
$self->[DEFINITIONS]->{$file} = $definition;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetDefinition
|
||||
#
|
||||
# Returns the <NaturalDocs::SourceDB::ItemDefinition>-derived object for the passed <FileName>, non-zero if it only tracks
|
||||
# existence, or undef if there is no definition.
|
||||
#
|
||||
sub GetDefinition #(FileName file) => NaturalDocs::SourceDB::ItemDefinition or bool
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{ return $self->[DEFINITIONS]->{$file}; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes the definition for the passed <FileName>. Returns whether it was successful, meaning whether a definition existed
|
||||
# for that file.
|
||||
#
|
||||
sub DeleteDefinition #(FileName file) => bool
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{
|
||||
if (exists $self->[DEFINITIONS]->{$file})
|
||||
{
|
||||
delete $self->[DEFINITIONS]->{$file};
|
||||
|
||||
if (!scalar keys %{$self->[DEFINITIONS]})
|
||||
{ $self->[DEFINITIONS] = undef; };
|
||||
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinitions
|
||||
#
|
||||
# Returns whether there are any definitions for this item.
|
||||
#
|
||||
sub HasDefinitions # => bool
|
||||
{
|
||||
my $self = shift;
|
||||
return (defined $self->[DEFINITIONS]);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinition
|
||||
#
|
||||
# Returns whether there is a definition for the passed <FileName>.
|
||||
#
|
||||
sub HasDefinition #(FileName file) => bool
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS])
|
||||
{ return (exists $self->[DEFINITIONS]->{$file}); }
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetAllDefinitionsHashRef
|
||||
#
|
||||
# Returns a hashref of all the definitions of this item. *Do not change.* The keys are the <FileNames>, and the values are
|
||||
# either <NaturalDocs::SourceDB::ItemDefinition>-derived objects or it's just an existence hashref if those aren't used.
|
||||
#
|
||||
sub GetAllDefinitionsHashRef
|
||||
{
|
||||
my $self = shift;
|
||||
return $self->[DEFINITIONS];
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,46 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB::ItemDefinition
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A base class for all item definitions for extensions that track more than existence.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB::ItemDefinition;
|
||||
|
||||
|
||||
#
|
||||
# Function: Compare
|
||||
#
|
||||
# Returns whether the definitions are equal. This version returns true by default, you must override it in your subclasses
|
||||
# to make the results relevant. This is important for <NaturalDocs::SourceDB->AnalyzeTrackedFileChanges()>.
|
||||
#
|
||||
# This will only be called between objects of the same <ExtensionID>. If you use multiple derived classes for the same
|
||||
# <ExtensionID>, you will have to take that into account yourself.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# other - Another <NaturalDocs::SourceDB::ItemDefinition>-derived object to compare this one to. It will always be from
|
||||
# the same <ExtensionID>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether they are equal.
|
||||
#
|
||||
sub Compare #(other)
|
||||
{
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,160 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SourceDB::WatchedFileDefinitions
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class to track the definitions appearing in a watched file. This is only used for extensions that track definition info with
|
||||
# <NaturalDocs::SourceDB::ItemDefinition>-derived objects. Do not use it for extensions that only track existence.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SourceDB::WatchedFileDefinitions;
|
||||
|
||||
|
||||
#
|
||||
# Variables: Members
|
||||
#
|
||||
# This object would only have one member, which is an array, so the object itself serves as that member.
|
||||
#
|
||||
# <ExtensionIDs> are used as indexes into this object. Each entry is a hashref that maps item strings to
|
||||
# <NaturalDocs::SourceDB::ItemDefinition>-derived objects. This is only done for extensions that use those objects to track
|
||||
# definitions, it's not needed for extensions that only track existence. If there are no definitions, the entry will be undef.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $class = shift;
|
||||
|
||||
my $object = [ ];
|
||||
bless $object, $class;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Definition Functions
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a definition for the passed item string. If it's already defined, the new definition will be ignored.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# extension - The <ExtensionID>.
|
||||
# itemString - The item string.
|
||||
# definition - The definition, which must be an object derived from <NaturalDocs::SourceDB::ItemDefinition>.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the definition was added, which is to say, whether this was the first definition for the passed <FileName>.
|
||||
#
|
||||
sub AddDefinition #(ExtensionID extension, string itemString, NaturalDocs::SourceDB::ItemDefinition definition) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString, $definition) = @_;
|
||||
|
||||
if (!defined $self->[$extension])
|
||||
{ $self->[$extension] = { }; };
|
||||
|
||||
if (!exists $self->[$extension]->{$itemString})
|
||||
{
|
||||
$self->[$extension]->{$itemString} = $definition;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GetDefinition
|
||||
#
|
||||
# Returns the <NaturalDocs::SourceDB::ItemDefinition>-derived object for the passed item string or undef if there is none.
|
||||
#
|
||||
sub GetDefinition #(ExtensionID extension, string itemString) => NaturalDocs::SourceDB::ItemDefinition
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $self->[$extension])
|
||||
{ return $self->[$extension]->{$itemString}; }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes the definition for the passed item string. Returns whether it was successful, meaning whether a definition existed
|
||||
# for that item.
|
||||
#
|
||||
sub DeleteDefinition #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $self->[$extension])
|
||||
{
|
||||
if (exists $self->[$extension]->{$itemString})
|
||||
{
|
||||
delete $self->[$extension]->{$itemString};
|
||||
|
||||
if (!scalar keys %{$self->[$extension]})
|
||||
{ $self->[$extension] = undef; };
|
||||
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinitions
|
||||
#
|
||||
# Returns whether there are any definitions for this item.
|
||||
#
|
||||
sub HasDefinitions #(ExtensionID extension) => bool
|
||||
{
|
||||
my ($self, $extension) = @_;
|
||||
|
||||
return (defined $self->[$extension]);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasDefinition
|
||||
#
|
||||
# Returns whether there is a definition for the passed item string.
|
||||
#
|
||||
sub HasDefinition #(ExtensionID extension, string itemString) => bool
|
||||
{
|
||||
my ($self, $extension, $itemString) = @_;
|
||||
|
||||
if (defined $self->[$extension])
|
||||
{ return (exists $self->[$extension]->{$itemString}); }
|
||||
else
|
||||
{ return 0; };
|
||||
};
|
||||
|
||||
|
||||
1;
|
103
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/StatusMessage.pm
Executable file
103
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/StatusMessage.pm
Executable file
@ -0,0 +1,103 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::StatusMessage
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to handle status message updates. Automatically handles <NaturalDocs::Settings->IsQuiet()>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::StatusMessage;
|
||||
|
||||
|
||||
#
|
||||
# var: message
|
||||
# The message to display.
|
||||
#
|
||||
my $message;
|
||||
|
||||
#
|
||||
# var: total
|
||||
# The number of items to work through.
|
||||
#
|
||||
my $total;
|
||||
|
||||
#
|
||||
# var: completed
|
||||
# The number of items completed.
|
||||
#
|
||||
my $completed;
|
||||
|
||||
#
|
||||
# var: lastMessageTime
|
||||
# The time the last message was posted.
|
||||
#
|
||||
my $lastMessageTime;
|
||||
|
||||
|
||||
#
|
||||
# constant: TIME_BETWEEN_UPDATES
|
||||
# The number of seconds that should occur between updates.
|
||||
#
|
||||
use constant TIME_BETWEEN_UPDATES => 10;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Function: Start
|
||||
#
|
||||
# Starts the status message.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# message - The message to post.
|
||||
# total - The number of items that are going to be worked through.
|
||||
#
|
||||
sub Start #(message, total)
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (!NaturalDocs::Settings->IsQuiet())
|
||||
{
|
||||
($message, $total) = @_;
|
||||
$completed = 0;
|
||||
|
||||
print $message . "\n";
|
||||
|
||||
$lastMessageTime = time();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CompletedItem
|
||||
#
|
||||
# Should be called every time an item is completed.
|
||||
#
|
||||
sub CompletedItem
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (!NaturalDocs::Settings->IsQuiet())
|
||||
{
|
||||
# We scale completed by 100 since we need to anyway to get the percentage.
|
||||
|
||||
$completed += 100;
|
||||
|
||||
if (time() >= $lastMessageTime + TIME_BETWEEN_UPDATES && $completed != $total * 100)
|
||||
{
|
||||
print $message . ' (' . ($completed / $total) . '%)' . "\n";
|
||||
$lastMessageTime = time();
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
1;
|
217
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolString.pm
Executable file
217
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolString.pm
Executable file
@ -0,0 +1,217 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SymbolString
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package to manage <SymbolString> handling throughout the program.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolString;
|
||||
|
||||
use Encode qw(encode_utf8 decode_utf8);
|
||||
|
||||
|
||||
#
|
||||
# Function: FromText
|
||||
#
|
||||
# Extracts and returns a <SymbolString> from plain text.
|
||||
#
|
||||
# This should be the only way to get a <SymbolString> from plain text, as the splitting and normalization must be consistent
|
||||
# throughout the application.
|
||||
#
|
||||
sub FromText #(string textSymbol)
|
||||
{
|
||||
my ($self, $textSymbol) = @_;
|
||||
|
||||
# The internal format of a symbol is all the normalized identifiers separated by 0x1F characters.
|
||||
|
||||
# Convert whitespace and reserved characters to spaces, and condense multiple consecutive ones.
|
||||
$textSymbol =~ tr/ \t\r\n\x1C\x1D\x1E\x1F/ /s;
|
||||
|
||||
# DEPENDENCY: ReferenceString->MakeFrom() assumes all 0x1E characters were removed.
|
||||
# DEPENDENCY: ReferenceString->MakeFrom() assumes this encoding doesn't use 0x1E characters.
|
||||
|
||||
# Remove spaces unless they're separating two alphanumeric/underscore characters.
|
||||
$textSymbol =~ s/^ //;
|
||||
$textSymbol =~ s/ $//;
|
||||
$textSymbol =~ s/(\W) /$1/g;
|
||||
$textSymbol =~ s/ (\W)/$1/g;
|
||||
|
||||
# Remove trailing empty parenthesis, so Function and Function() are equivalent.
|
||||
$textSymbol =~ s/\(\)$//;
|
||||
|
||||
# Split the string into pieces.
|
||||
my @pieces = split(/(\.|::|->)/, $textSymbol);
|
||||
my $symbolString;
|
||||
|
||||
my $lastWasSeparator = 1;
|
||||
|
||||
foreach my $piece (@pieces)
|
||||
{
|
||||
if ($piece =~ /^(?:\.|::|->)$/)
|
||||
{
|
||||
if (!$lastWasSeparator)
|
||||
{
|
||||
$symbolString .= "\x1F";
|
||||
$lastWasSeparator = 1;
|
||||
};
|
||||
}
|
||||
elsif (length $piece)
|
||||
{
|
||||
$symbolString .= $piece;
|
||||
$lastWasSeparator = 0;
|
||||
};
|
||||
# Ignore empty pieces
|
||||
};
|
||||
|
||||
$symbolString =~ s/\x1F$//;
|
||||
|
||||
return $symbolString;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToText
|
||||
#
|
||||
# Converts a <SymbolString> to text, using the passed separator.
|
||||
#
|
||||
sub ToText #(SymbolString symbolString, string separator)
|
||||
{
|
||||
my ($self, $symbolString, $separator) = @_;
|
||||
|
||||
my @identifiers = $self->IdentifiersOf($symbolString);
|
||||
return join($separator, @identifiers);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToBinaryFile
|
||||
#
|
||||
# Writes a <SymbolString> to the passed filehandle. Can also encode an undef.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The filehandle to write to.
|
||||
# symbol - The <SymbolString> to write, or undef.
|
||||
#
|
||||
# Format:
|
||||
#
|
||||
# > [UInt8: number of identifiers]
|
||||
# > [UString16: identifier] [UString16: identifier] ...
|
||||
#
|
||||
# Undef is represented by a zero for the number of identifiers.
|
||||
#
|
||||
sub ToBinaryFile #(FileHandle fileHandle, SymbolString symbol)
|
||||
{
|
||||
my ($self, $fileHandle, $symbol) = @_;
|
||||
|
||||
my @identifiers;
|
||||
if (defined $symbol)
|
||||
{ @identifiers = $self->IdentifiersOf($symbol); };
|
||||
|
||||
print $fileHandle pack('C', scalar @identifiers);
|
||||
|
||||
foreach my $identifier (@identifiers)
|
||||
{
|
||||
my $uIdentifier = encode_utf8($identifier);
|
||||
print $fileHandle pack('na*', length($uIdentifier), $uIdentifier);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromBinaryFile
|
||||
#
|
||||
# Loads a <SymbolString> or undef from the filehandle and returns it.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The filehandle to read from.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The <SymbolString> or undef.
|
||||
#
|
||||
# See also:
|
||||
#
|
||||
# See <ToBinaryFile()> for format and dependencies.
|
||||
#
|
||||
sub FromBinaryFile #(FileHandle fileHandle)
|
||||
{
|
||||
my ($self, $fileHandle) = @_;
|
||||
|
||||
my $raw;
|
||||
|
||||
# [UInt8: number of identifiers or 0 if none]
|
||||
|
||||
read($fileHandle, $raw, 1);
|
||||
my $identifierCount = unpack('C', $raw);
|
||||
|
||||
my @identifiers;
|
||||
|
||||
while ($identifierCount)
|
||||
{
|
||||
# [UString16: identifier] [UString16: identifier] ...
|
||||
|
||||
read($fileHandle, $raw, 2);
|
||||
my $identifierLength = unpack('n', $raw);
|
||||
|
||||
my $identifier;
|
||||
read($fileHandle, $identifier, $identifierLength);
|
||||
$identifier = decode_utf8($identifier);
|
||||
|
||||
push @identifiers, $identifier;
|
||||
|
||||
$identifierCount--;
|
||||
};
|
||||
|
||||
if (scalar @identifiers)
|
||||
{ return $self->Join(@identifiers); }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IdentifiersOf
|
||||
#
|
||||
# Returns the <SymbolString> as an array of identifiers.
|
||||
#
|
||||
sub IdentifiersOf #(SymbolString symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
return split(/\x1F/, $symbol);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Join
|
||||
#
|
||||
# Takes a list of identifiers and/or <SymbolStrings> and returns it as a new <SymbolString>.
|
||||
#
|
||||
sub Join #(string/SymbolString identifier/symbol, string/SymolString identifier/symbol, ...)
|
||||
{
|
||||
my ($self, @pieces) = @_;
|
||||
|
||||
# Can't have undefs screwing everything up.
|
||||
while (scalar @pieces && !defined $pieces[0])
|
||||
{ shift @pieces; };
|
||||
|
||||
# We need to test @pieces first because joining on an empty array returns an empty string rather than undef.
|
||||
if (scalar @pieces)
|
||||
{ return join("\x1F", @pieces); }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
1;
|
2016
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable.pm
Executable file
2016
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable.pm
Executable file
File diff suppressed because it is too large
Load Diff
187
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/File.pm
Executable file
187
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/File.pm
Executable file
@ -0,0 +1,187 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SymbolTable::File
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing a file, keeping track of what symbols and references are defined in it.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolTable::File;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# SYMBOLS - An existence hashref of the <SymbolStrings> it defines.
|
||||
# REFERENCES - An existence hashref of the <ReferenceStrings> in the file.
|
||||
#
|
||||
|
||||
# DEPENDENCY: New() depends on the order of these constants. If they change, New() has to be updated.
|
||||
use constant SYMBOLS => 0;
|
||||
use constant REFERENCES => 1;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $package = shift;
|
||||
|
||||
# Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error.
|
||||
if (scalar @_)
|
||||
{ die "You can't pass values to NaturalDocs::SymbolTable::File->New()\n"; };
|
||||
|
||||
# DEPENDENCY: This code depends on the order of the member constants.
|
||||
my $object = [ { }, { } ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddSymbol
|
||||
#
|
||||
# Adds a <SymbolString> definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString> being added.
|
||||
#
|
||||
sub AddSymbol #(symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
$self->[SYMBOLS]{$symbol} = 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteSymbol
|
||||
#
|
||||
# Removes a <SymbolString> definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString> to delete.
|
||||
#
|
||||
sub DeleteSymbol #(symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
delete $self->[SYMBOLS]{$symbol};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddReference
|
||||
#
|
||||
# Adds a reference definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# referenceString - The <ReferenceString> being added.
|
||||
#
|
||||
sub AddReference #(referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
$self->[REFERENCES]{$referenceString} = 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteReference
|
||||
#
|
||||
# Removes a reference definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# referenceString - The <ReferenceString> to delete.
|
||||
#
|
||||
sub DeleteReference #(referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
delete $self->[REFERENCES]{$referenceString};
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: HasAnything
|
||||
#
|
||||
# Returns whether the file has any symbol or reference definitions at all.
|
||||
#
|
||||
sub HasAnything
|
||||
{
|
||||
return (scalar keys %{$_[0]->[SYMBOLS]} || scalar keys %{$_[0]->[REFERENCES]});
|
||||
};
|
||||
|
||||
#
|
||||
# Function: Symbols
|
||||
#
|
||||
# Returns an array of all the <SymbolStrings> defined in this file. If none, returns an empty array.
|
||||
#
|
||||
sub Symbols
|
||||
{
|
||||
return keys %{$_[0]->[SYMBOLS]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: References
|
||||
#
|
||||
# Returns an array of all the <ReferenceStrings> defined in this file. If none, returns an empty array.
|
||||
#
|
||||
sub References
|
||||
{
|
||||
return keys %{$_[0]->[REFERENCES]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DefinesSymbol
|
||||
#
|
||||
# Returns whether the file defines the passed <SymbolString> or not.
|
||||
#
|
||||
sub DefinesSymbol #(symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
return exists $self->[SYMBOLS]{$symbol};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DefinesReference
|
||||
#
|
||||
# Returns whether the file defines the passed <ReferenceString> or not.
|
||||
#
|
||||
sub DefinesReference #(referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
return exists $self->[REFERENCES]{$referenceString};
|
||||
};
|
||||
|
||||
1;
|
@ -0,0 +1,523 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::SymbolTable::IndexElement
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing part of an indexed symbol.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use Tie::RefHash;
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::SymbolTable::IndexElement;
|
||||
|
||||
|
||||
#
|
||||
# Topic: How IndexElements Work
|
||||
#
|
||||
# This is a little tricky, so make sure you understand this. Indexes are sorted by symbol, then packages, then file. If there is only
|
||||
# one package for a symbol, or one file definition for a package/symbol, they are added inline to the entry. However, if there are
|
||||
# multiple packages or files, the function for it returns an arrayref of IndexElements instead. Which members are defined and
|
||||
# undefined should follow common sense. For example, if a symbol is defined in multiple packages, the symbol's IndexElement
|
||||
# will not define <File()>, <Type()>, or <Prototype()>; those will be defined in child elements. Similarly, the child elements will
|
||||
# not define <Symbol()> since it's redundant.
|
||||
#
|
||||
# Diagrams may be clearer. If a member isn't listed for an element, it isn't defined.
|
||||
#
|
||||
# A symbol that only has one package and file:
|
||||
# > [Element]
|
||||
# > - Symbol
|
||||
# > - Package
|
||||
# > - File
|
||||
# > - Type
|
||||
# > - Prototype
|
||||
# > - Summary
|
||||
#
|
||||
# A symbol that is defined by multiple packages, each with only one file:
|
||||
# > [Element]
|
||||
# > - Symbol
|
||||
# > - Package
|
||||
# > [Element]
|
||||
# > - Package
|
||||
# > - File
|
||||
# > - Type
|
||||
# > - Prototype
|
||||
# > - Summary
|
||||
# > [Element]
|
||||
# > - ...
|
||||
#
|
||||
# A symbol that is defined by one package, but has multiple files
|
||||
# > [Element]
|
||||
# > - Symbol
|
||||
# > - Package
|
||||
# > - File
|
||||
# > [Element]
|
||||
# > - File
|
||||
# > - Type
|
||||
# > - Protype
|
||||
# > - Summary
|
||||
# > [Element]
|
||||
# > - ...
|
||||
#
|
||||
# A symbol that is defined by multiple packages which have multiple files:
|
||||
# > [Element]
|
||||
# > - Symbol
|
||||
# > - Package
|
||||
# > [Element]
|
||||
# > - Package
|
||||
# > - File
|
||||
# > [Element]
|
||||
# > - File
|
||||
# > - Type
|
||||
# > - Prototype
|
||||
# > - Summary
|
||||
# > [Element]
|
||||
# > - ...
|
||||
# > [Element]
|
||||
# > - ...
|
||||
#
|
||||
# Why is it done this way?:
|
||||
#
|
||||
# Because it makes it easier to generate nice indexes since all the splitting and combining is done for you. If a symbol
|
||||
# has only one package, you just want to link to it, you don't want to break out a subindex for just one package. However, if
|
||||
# it has multiple package, you do want the subindex and to link to each one individually. Use <HasMultiplePackages()> and
|
||||
# <HasMultipleFiles()> to determine whether you need to add a subindex for it.
|
||||
#
|
||||
#
|
||||
# Combining Properties:
|
||||
#
|
||||
# All IndexElements also have combining properties set.
|
||||
#
|
||||
# CombinedType - The general <TopicType> of the entry. Conflicts combine into <TOPIC_GENERAL>.
|
||||
# PackageSeparator - The package separator symbol of the entry. Conflicts combine into a dot.
|
||||
#
|
||||
# So if an IndexElement only has one definition, <CombinedType()> is the same as the <TopicType> and <PackageSeparator()>
|
||||
# is that of the definition's language. If other definitions are added and they have the same properties, the combined properties
|
||||
# will remain the same. However, if they're different, they switch values as noted above.
|
||||
#
|
||||
#
|
||||
# Sortable Symbol:
|
||||
#
|
||||
# <SortableSymbol()> is a pseudo-combining property. There were a few options for dealing with multiple languages defining
|
||||
# the same symbol but stripping different prefixes off it, but ultimately I decided to go with whatever the language does that
|
||||
# has the most definitions. There's not likely to be many conflicts here in the real world; probably the only thing would be
|
||||
# defining it in a text file and forgetting to specify the prefixes to strip there too. So this works.
|
||||
#
|
||||
# Ties are broken pretty much randomly, except that text files always lose if its one of the options.
|
||||
#
|
||||
# It's a pseudo-combining property because it's done after the IndexElements are all filled in and only stored in the top-level
|
||||
# ones.
|
||||
#
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# SYMBOL - The <SymbolString> without the package portion.
|
||||
# PACKAGE - The package <SymbolString>. Will be a package <SymbolString>, undef for global, or an arrayref of
|
||||
# <NaturalDocs::SymbolTable::IndexElement> objects if multiple packages define the symbol.
|
||||
# FILE - The <FileName> the package/symbol is defined in. Will be the file name or an arrayref of
|
||||
# <NaturalDocs::SymbolTable::IndexElements> if multiple files define the package/symbol.
|
||||
# TYPE - The package/symbol/file <TopicType>.
|
||||
# PROTOTYPE - The package/symbol/file prototype, or undef if not applicable.
|
||||
# SUMMARY - The package/symbol/file summary, or undef if not applicable.
|
||||
# COMBINED_TYPE - The combined <TopicType> of the element.
|
||||
# PACKAGE_SEPARATOR - The combined package separator symbol of the element.
|
||||
# SORTABLE_SYMBOL - The sortable symbol as a text string.
|
||||
# IGNORED_PREFIX - The part of the symbol that was stripped off to make the sortable symbol.
|
||||
#
|
||||
use NaturalDocs::DefineMembers 'SYMBOL', 'Symbol()',
|
||||
'PACKAGE', 'Package()',
|
||||
'FILE', 'File()',
|
||||
'TYPE', 'Type()',
|
||||
'PROTOTYPE', 'Prototype()',
|
||||
'SUMMARY', 'Summary()',
|
||||
'COMBINED_TYPE', 'CombinedType()',
|
||||
'PACKAGE_SEPARATOR', 'PackageSeparator()',
|
||||
'SORTABLE_SYMBOL', 'SortableSymbol()',
|
||||
'IGNORED_PREFIX', 'IgnoredPrefix()';
|
||||
# DEPENDENCY: New() depends on the order of these constants and that there is no inheritance..
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Returns a new object.
|
||||
#
|
||||
# This should only be used for creating an entirely new symbol. You should *not* pass arrayrefs as package or file parameters
|
||||
# if you are calling this externally. Use <Merge()> instead.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString> without the package portion.
|
||||
# package - The package <SymbolString>, or undef for global.
|
||||
# file - The symbol's definition file.
|
||||
# type - The symbol's <TopicType>.
|
||||
# prototype - The symbol's prototype, if applicable.
|
||||
# summary - The symbol's summary, if applicable.
|
||||
#
|
||||
# Optional Parameters:
|
||||
#
|
||||
# These parameters don't need to be specified. You should ignore them when calling this externally.
|
||||
#
|
||||
# combinedType - The symbol's combined <TopicType>.
|
||||
# packageSeparator - The symbol's combined package separator symbol.
|
||||
#
|
||||
sub New #(symbol, package, file, type, prototype, summary, combinedType, packageSeparator)
|
||||
{
|
||||
# DEPENDENCY: This depends on the parameter list being in the same order as the constants.
|
||||
|
||||
my $self = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $self;
|
||||
|
||||
if (!defined $object->[COMBINED_TYPE])
|
||||
{ $object->[COMBINED_TYPE] = $object->[TYPE]; };
|
||||
|
||||
if (!defined $object->[PACKAGE_SEPARATOR])
|
||||
{
|
||||
if ($object->[TYPE] eq ::TOPIC_FILE())
|
||||
{ $object->[PACKAGE_SEPARATOR] = '.'; }
|
||||
else
|
||||
{
|
||||
$object->[PACKAGE_SEPARATOR] = NaturalDocs::Languages->LanguageOf($object->[FILE])->PackageSeparator();
|
||||
};
|
||||
};
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Merge
|
||||
#
|
||||
# Adds another definition of the same symbol. Perhaps it has a different package or defining file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# package - The package <SymbolString>, or undef for global.
|
||||
# file - The symbol's definition file.
|
||||
# type - The symbol's <TopicType>.
|
||||
# prototype - The symbol's protoype if applicable.
|
||||
# summary - The symbol's summary if applicable.
|
||||
#
|
||||
sub Merge #(package, file, type, prototype, summary)
|
||||
{
|
||||
my ($self, $package, $file, $type, $prototype, $summary) = @_;
|
||||
|
||||
# If there's only one package...
|
||||
if (!$self->HasMultiplePackages())
|
||||
{
|
||||
# If there's one package and it's the same as the new one...
|
||||
if ($package eq $self->Package())
|
||||
{
|
||||
$self->MergeFile($file, $type, $prototype, $summary);
|
||||
}
|
||||
|
||||
# If there's one package and the new one is different...
|
||||
else
|
||||
{
|
||||
my $selfDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $self->Package(), $self->File(),
|
||||
$self->Type(), $self->Prototype(),
|
||||
$self->Summary(), $self->CombinedType(),
|
||||
$self->PackageSeparator());
|
||||
my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $package, $file, $type, $prototype,
|
||||
$summary);
|
||||
|
||||
$self->[PACKAGE] = [ $selfDefinition, $newDefinition ];
|
||||
$self->[FILE] = undef;
|
||||
$self->[TYPE] = undef;
|
||||
$self->[PROTOTYPE] = undef;
|
||||
$self->[SUMMARY] = undef;
|
||||
|
||||
if ($newDefinition->Type() ne $self->CombinedType())
|
||||
{ $self->[COMBINED_TYPE] = ::TOPIC_GENERAL(); };
|
||||
if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
|
||||
{ $self->[PACKAGE_SEPARATOR] = '.'; };
|
||||
};
|
||||
}
|
||||
|
||||
# If there's more than one package...
|
||||
else
|
||||
{
|
||||
# See if the new package is one of them.
|
||||
my $selfPackages = $self->Package();
|
||||
my $matchingPackage;
|
||||
|
||||
foreach my $testPackage (@$selfPackages)
|
||||
{
|
||||
if ($package eq $testPackage->Package())
|
||||
{
|
||||
$testPackage->MergeFile($file, $type, $prototype, $summary);;
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, $package, $file, $type, $prototype,
|
||||
$summary);
|
||||
push @{$self->[PACKAGE]}, $newDefinition;
|
||||
|
||||
if ($newDefinition->Type() ne $self->CombinedType())
|
||||
{ $self->[COMBINED_TYPE] = ::TOPIC_GENERAL(); };
|
||||
if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
|
||||
{ $self->[PACKAGE_SEPARATOR] = '.'; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Sort
|
||||
#
|
||||
# Sorts the package and file lists of the symbol.
|
||||
#
|
||||
sub Sort
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if ($self->HasMultipleFiles())
|
||||
{
|
||||
@{$self->[FILE]} = sort { ::StringCompare($a->File(), $b->File()) } @{$self->File()};
|
||||
}
|
||||
|
||||
elsif ($self->HasMultiplePackages())
|
||||
{
|
||||
@{$self->[PACKAGE]} = sort { ::StringCompare( $a->Package(), $b->Package()) } @{$self->[PACKAGE]};
|
||||
|
||||
foreach my $packageElement ( @{$self->[PACKAGE]} )
|
||||
{
|
||||
if ($packageElement->HasMultipleFiles())
|
||||
{ $packageElement->Sort(); };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: MakeSortableSymbol
|
||||
#
|
||||
# Generates <SortableSymbol()> and <IgnoredPrefix()>. Should only be called after everything is merged.
|
||||
#
|
||||
sub MakeSortableSymbol
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $finalLanguage;
|
||||
|
||||
if ($self->HasMultiplePackages() || $self->HasMultipleFiles())
|
||||
{
|
||||
# Collect all the files that define this symbol.
|
||||
|
||||
my @files;
|
||||
|
||||
if ($self->HasMultipleFiles())
|
||||
{
|
||||
my $fileElements = $self->File();
|
||||
|
||||
foreach my $fileElement (@$fileElements)
|
||||
{ push @files, $fileElement->File(); };
|
||||
}
|
||||
else # HasMultiplePackages
|
||||
{
|
||||
my $packages = $self->Package();
|
||||
|
||||
foreach my $package (@$packages)
|
||||
{
|
||||
if ($package->HasMultipleFiles())
|
||||
{
|
||||
my $fileElements = $package->File();
|
||||
|
||||
foreach my $fileElement (@$fileElements)
|
||||
{ push @files, $fileElement->File(); };
|
||||
}
|
||||
else
|
||||
{ push @files, $package->File(); };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# Determine which language defines it the most.
|
||||
|
||||
# Keys are language objects, values are counts.
|
||||
my %languages;
|
||||
tie %languages, 'Tie::RefHash';
|
||||
|
||||
foreach my $file (@files)
|
||||
{
|
||||
my $language = NaturalDocs::Languages->LanguageOf($file);
|
||||
|
||||
if (exists $languages{$language})
|
||||
{ $languages{$language}++; }
|
||||
else
|
||||
{ $languages{$language} = 1; };
|
||||
};
|
||||
|
||||
my $topCount = 0;
|
||||
my @topLanguages;
|
||||
|
||||
while (my ($language, $count) = each %languages)
|
||||
{
|
||||
if ($count > $topCount)
|
||||
{
|
||||
$topCount = $count;
|
||||
@topLanguages = ( $language );
|
||||
}
|
||||
elsif ($count == $topCount)
|
||||
{
|
||||
push @topLanguages, $language;
|
||||
};
|
||||
};
|
||||
|
||||
if (scalar @topLanguages == 1)
|
||||
{ $finalLanguage = $topLanguages[0]; }
|
||||
else
|
||||
{
|
||||
if ($topLanguages[0]->Name() ne 'Text File')
|
||||
{ $finalLanguage = $topLanguages[0]; }
|
||||
else
|
||||
{ $finalLanguage = $topLanguages[1]; };
|
||||
};
|
||||
}
|
||||
|
||||
else # !hasMultiplePackages && !hasMultipleFiles
|
||||
{ $finalLanguage = NaturalDocs::Languages->LanguageOf($self->File()); };
|
||||
|
||||
my $textSymbol = NaturalDocs::SymbolString->ToText($self->Symbol(), $self->PackageSeparator());
|
||||
my $ignoredPrefixLength = $finalLanguage->IgnoredPrefixLength($textSymbol, $self->CombinedType());
|
||||
|
||||
if ($ignoredPrefixLength)
|
||||
{
|
||||
$self->[IGNORED_PREFIX] = substr($textSymbol, 0, $ignoredPrefixLength);
|
||||
$self->[SORTABLE_SYMBOL] = substr($textSymbol, $ignoredPrefixLength);
|
||||
}
|
||||
else
|
||||
{ $self->[SORTABLE_SYMBOL] = $textSymbol; };
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Functions: Information Functions
|
||||
#
|
||||
# Symbol - Returns the <SymbolString> without the package portion.
|
||||
# Package - If <HasMultiplePackages()> is true, returns an arrayref of <NaturalDocs::SymbolTable::IndexElement> objects.
|
||||
# Otherwise returns the package <SymbolString>, or undef if global.
|
||||
# File - If <HasMultipleFiles()> is true, returns an arrayref of <NaturalDocs::SymbolTable::IndexElement> objects. Otherwise
|
||||
# returns the name of the definition file.
|
||||
# Type - Returns the <TopicType> of the package/symbol/file, if applicable.
|
||||
# Prototype - Returns the prototype of the package/symbol/file, if applicable.
|
||||
# Summary - Returns the summary of the package/symbol/file, if applicable.
|
||||
# CombinedType - Returns the combined <TopicType> of the element.
|
||||
# PackageSeparator - Returns the combined package separator symbol of the element.
|
||||
# SortableSymbol - Returns the sortable symbol as a text string. Only available after calling <MakeSortableSymbol()>.
|
||||
# IgnoredPrefix - Returns the part of the symbol that was stripped off to make the <SortableSymbol()>, or undef if none.
|
||||
# Only available after calling <MakeSortableSymbol()>.
|
||||
#
|
||||
|
||||
# Function: HasMultiplePackages
|
||||
# Returns whether <Packages()> is broken out into more elements.
|
||||
sub HasMultiplePackages
|
||||
{ return ref($_[0]->[PACKAGE]); };
|
||||
|
||||
# Function: HasMultipleFiles
|
||||
# Returns whether <File()> is broken out into more elements.
|
||||
sub HasMultipleFiles
|
||||
{ return ref($_[0]->[FILE]); };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Support Functions
|
||||
|
||||
#
|
||||
# Function: MergeFile
|
||||
#
|
||||
# Adds another definition of the same package/symbol. Perhaps the file is different.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The package/symbol's definition file.
|
||||
# type - The package/symbol's <TopicType>.
|
||||
# prototype - The package/symbol's protoype if applicable.
|
||||
# summary - The package/symbol's summary if applicable.
|
||||
#
|
||||
sub MergeFile #(file, type, prototype, summary)
|
||||
{
|
||||
my ($self, $file, $type, $prototype, $summary) = @_;
|
||||
|
||||
# If there's only one file...
|
||||
if (!$self->HasMultipleFiles())
|
||||
{
|
||||
# If there's one file and it's the different from the new one...
|
||||
if ($file ne $self->File())
|
||||
{
|
||||
my $selfDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $self->File(), $self->Type(),
|
||||
$self->Prototype(), $self->Summary(),
|
||||
$self->CombinedType(),
|
||||
$self->PackageSeparator());
|
||||
my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $file, $type, $prototype,
|
||||
$summary);
|
||||
|
||||
$self->[FILE] = [ $selfDefinition, $newDefinition ];
|
||||
$self->[TYPE] = undef;
|
||||
$self->[PROTOTYPE] = undef;
|
||||
$self->[SUMMARY] = undef;
|
||||
|
||||
if ($newDefinition->Type() ne $self->CombinedType())
|
||||
{ $self->[COMBINED_TYPE] = ::TOPIC_GENERAL(); };
|
||||
if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
|
||||
{ $self->[PACKAGE_SEPARATOR] = '.'; };
|
||||
}
|
||||
|
||||
# If the file was the same, just ignore the duplicate in the index.
|
||||
}
|
||||
|
||||
# If there's more than one file...
|
||||
else
|
||||
{
|
||||
# See if the new file is one of them.
|
||||
my $files = $self->File();
|
||||
|
||||
foreach my $testElement (@$files)
|
||||
{
|
||||
if ($testElement->File() eq $file)
|
||||
{
|
||||
# If the new file's already in the index, ignore the duplicate.
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
my $newDefinition = NaturalDocs::SymbolTable::IndexElement->New(undef, undef, $file, $type, $prototype,
|
||||
$summary);
|
||||
push @{$self->[FILE]}, $newDefinition;
|
||||
|
||||
if ($newDefinition->Type() ne $self->CombinedType())
|
||||
{ $self->[COMBINED_TYPE] = ::TOPIC_GENERAL(); };
|
||||
if ($newDefinition->PackageSeparator() ne $self->PackageSeparator())
|
||||
{ $self->[PACKAGE_SEPARATOR] = '.'; };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
1;
|
274
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Reference.pm
Executable file
274
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Reference.pm
Executable file
@ -0,0 +1,274 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SymbolTable::Reference
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing a symbol or a potential symbol.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolTable::Reference;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# DEFINITIONS - An existence hashref of the <FileNames> that define this reference.
|
||||
# INTERPRETATIONS - A hashref of the possible interpretations of this reference. The keys are the <SymbolStrings>
|
||||
# and the values are the scores.
|
||||
# CURRENT_INTERPRETATION - The interpretation currently used as the reference target. It will be the interpretation with
|
||||
# the highest score that is actually defined. If none are defined, this item will be undef.
|
||||
#
|
||||
|
||||
# DEPENDENCY: New() depends on the order of these constants. If they change, New() has to be updated.
|
||||
use constant DEFINITIONS => 0;
|
||||
use constant INTERPRETATIONS => 1;
|
||||
use constant CURRENT_INTERPRETATION => 2;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $package = shift;
|
||||
|
||||
# Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error.
|
||||
if (scalar @_)
|
||||
{ die "You can't pass values to NaturalDocs::SymbolTable::Reference->New()\n"; };
|
||||
|
||||
# DEPENDENCY: This code depends on the order of the member constants.
|
||||
my $object = [ { }, { }, undef ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a reference definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> that defines the reference.
|
||||
#
|
||||
sub AddDefinition #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
$self->[DEFINITIONS]{$file} = 1;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes a reference definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> which has the definition to delete.
|
||||
#
|
||||
sub DeleteDefinition #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
delete $self->[DEFINITIONS]{$file};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddInterpretation
|
||||
#
|
||||
# Adds a symbol that this reference can be interpreted as.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString>.
|
||||
# score - The score of this interpretation.
|
||||
#
|
||||
sub AddInterpretation #(symbol, score)
|
||||
{
|
||||
my ($self, $symbol, $score) = @_;
|
||||
|
||||
$self->[INTERPRETATIONS]{$symbol} = $score;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteInterpretation
|
||||
#
|
||||
# Deletes a symbol that this reference can be interpreted as.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString> to delete.
|
||||
#
|
||||
sub DeleteInterpretation #(symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
|
||||
delete $self->[INTERPRETATIONS]{$symbol};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteAllInterpretationsButCurrent
|
||||
#
|
||||
# Deletes all interpretations except for the current one.
|
||||
#
|
||||
sub DeleteAllInterpretationsButCurrent
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if ($self->HasCurrentInterpretation())
|
||||
{
|
||||
my $score = $self->CurrentScore();
|
||||
|
||||
# Fastest way to clear a hash except for one item? Make a new hash with just that item.
|
||||
%{$self->[INTERPRETATIONS]} = ( $self->[CURRENT_INTERPRETATION] => $score );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetCurrentInterpretation
|
||||
#
|
||||
# Changes the current interpretation. The new one must already have been added via <AddInterpretation()>.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The <SymbolString>l to make the current interpretation. Can be set to undef to clear it.
|
||||
#
|
||||
sub SetCurrentInterpretation #(symbol)
|
||||
{
|
||||
my ($self, $symbol) = @_;
|
||||
|
||||
$self->[CURRENT_INTERPRETATION] = $symbol;
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: Definitions
|
||||
#
|
||||
# Returns an array of all the <FileNames> that define this reference. If none do, returns an empty array.
|
||||
#
|
||||
sub Definitions
|
||||
{
|
||||
return keys %{$_[0]->[DEFINITIONS]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsDefined
|
||||
#
|
||||
# Returns whether the reference has any definitions or not.
|
||||
#
|
||||
sub IsDefined
|
||||
{
|
||||
return scalar keys %{$_[0]->[DEFINITIONS]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsDefinedIn
|
||||
#
|
||||
# Returns whether the reference is defined in the passed <FileName>.
|
||||
#
|
||||
sub IsDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
return exists $self->[DEFINITIONS]{$file};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Interpretations
|
||||
#
|
||||
# Returns an array of all the <SymbolStrings> that this reference can be interpreted as. If none, returns an empty array.
|
||||
#
|
||||
sub Interpretations
|
||||
{
|
||||
return keys %{$_[0]->[INTERPRETATIONS]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: InterpretationsAndScores
|
||||
#
|
||||
# Returns a hash of all the <SymbolStrings> that this reference can be interpreted as and their scores. The keys are the <SymbolStrings>
|
||||
# and the values are the scores. If none, returns an empty hash.
|
||||
#
|
||||
sub InterpretationsAndScores
|
||||
{
|
||||
return %{$_[0]->[INTERPRETATIONS]};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasCurrentInterpretation
|
||||
#
|
||||
# Returns whether the reference has a current interpretation or not.
|
||||
#
|
||||
sub HasCurrentInterpretation
|
||||
{
|
||||
return defined $_[0]->[CURRENT_INTERPRETATION];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CurrentInterpretation
|
||||
#
|
||||
# Returns the <SymbolString> of the current interpretation, or undef if none.
|
||||
#
|
||||
sub CurrentInterpretation
|
||||
{
|
||||
return $_[0]->[CURRENT_INTERPRETATION];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CurrentScore
|
||||
#
|
||||
# Returns the score of the current interpretation, or undef if none.
|
||||
#
|
||||
sub CurrentScore
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (defined $self->[CURRENT_INTERPRETATION])
|
||||
{
|
||||
return $self->[INTERPRETATIONS]{ $self->[CURRENT_INTERPRETATION] };
|
||||
}
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
1;
|
@ -0,0 +1,98 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Class: NaturalDocs::SymbolTable::ReferenceTarget
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class for storing information about a reference target.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolTable::ReferenceTarget;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# SYMBOL - The target <SymbolString>.
|
||||
# FILE - The <FileName> the target is defined in.
|
||||
# TYPE - The target <TopicType>.
|
||||
# PROTOTYPE - The target's prototype, or undef if none.
|
||||
# SUMMARY - The target's summary, or undef if none.
|
||||
#
|
||||
|
||||
# DEPENDENCY: New() depends on the order of these constants. If they change, New() has to be updated.
|
||||
use constant SYMBOL => 0;
|
||||
use constant FILE => 1;
|
||||
use constant TYPE => 2;
|
||||
use constant PROTOTYPE => 3;
|
||||
use constant SUMMARY => 4;
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# symbol - The target <SymbolString>.
|
||||
# file - The <FileName> the target is defined in.
|
||||
# type - The <TopicType> of the target symbol.
|
||||
# prototype - The target's prototype. Set to undef if not defined or not applicable.
|
||||
# summary - The target's summary. Set to undef if not defined or not applicable.
|
||||
#
|
||||
sub New #(symbol, file, type, prototype, summary)
|
||||
{
|
||||
# DEPENDENCY: This code depends on the order of the member constants.
|
||||
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Symbol
|
||||
# Returns the target's <SymbolString>.
|
||||
sub Symbol
|
||||
{ return $_[0]->[SYMBOL]; };
|
||||
|
||||
# Function: File
|
||||
# Returns the <FileName> the target is defined in.
|
||||
sub File
|
||||
{ return $_[0]->[FILE]; };
|
||||
|
||||
# Function: Type
|
||||
# Returns the target's <TopicType>.
|
||||
sub Type
|
||||
{ return $_[0]->[TYPE]; };
|
||||
|
||||
# Function: Prototype
|
||||
# Returns the target's prototype, or undef if not defined or not applicable.
|
||||
sub Prototype
|
||||
{ return $_[0]->[PROTOTYPE]; };
|
||||
|
||||
# Function: Summary
|
||||
# Returns the target's summary, or undef if not defined or not applicable.
|
||||
sub Summary
|
||||
{ return $_[0]->[SUMMARY]; };
|
||||
|
||||
1;
|
429
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Symbol.pm
Executable file
429
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/SymbolTable/Symbol.pm
Executable file
@ -0,0 +1,429 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SymbolTable::Symbol
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing a symbol or a potential symbol.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolTable::Symbol;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# DEFINITIONS - A hashref of all the files which define this symbol. The keys are the <FileNames>, and the values are
|
||||
# <NaturalDocs::SymbolTable::SymbolDefinition> objects. If no files define this symbol, this item will
|
||||
# be undef.
|
||||
# GLOBAL_DEFINITION - The <FileName> which defines the global version of the symbol, which is what is used if
|
||||
# a file references the symbol but does not have its own definition. If there are no definitions, this
|
||||
# item will be undef.
|
||||
# REFERENCES - A hashref of the references that can be interpreted as this symbol. This doesn't mean these
|
||||
# references necessarily are. The keys are the reference strings, and the values are the scores of
|
||||
# the interpretations. If no references can be interpreted as this symbol, this item will be undef.
|
||||
#
|
||||
use constant DEFINITIONS => 0;
|
||||
use constant GLOBAL_DEFINITION => 1;
|
||||
use constant REFERENCES => 2;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Modification Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
sub New
|
||||
{
|
||||
my $package = shift;
|
||||
|
||||
# Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error.
|
||||
if (scalar @_)
|
||||
{ die "You can't pass values to NaturalDocs::SymbolTable::Symbol->New()\n"; };
|
||||
|
||||
my $object = [ undef, undef, undef ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
#
|
||||
# Function: AddDefinition
|
||||
#
|
||||
# Adds a symbol definition. If this is the first definition for this symbol, it will become the global definition. If the definition
|
||||
# already exists for the file, it will be ignored.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> that defines the symbol.
|
||||
# type - The <TopicType> of the definition.
|
||||
# prototype - The prototype of the definition, if applicable. Undef otherwise.
|
||||
# summary - The summary for the definition, if applicable. Undef otherwise.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether this provided the first definition for this symbol.
|
||||
#
|
||||
sub AddDefinition #(file, type, prototype, summary)
|
||||
{
|
||||
my ($self, $file, $type, $prototype, $summary) = @_;
|
||||
|
||||
my $isFirst;
|
||||
|
||||
if (!defined $self->[DEFINITIONS])
|
||||
{
|
||||
$self->[DEFINITIONS] = { };
|
||||
$self->[GLOBAL_DEFINITION] = $file;
|
||||
$isFirst = 1;
|
||||
};
|
||||
|
||||
if (!exists $self->[DEFINITIONS]{$file})
|
||||
{
|
||||
$self->[DEFINITIONS]{$file} = NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
|
||||
};
|
||||
|
||||
return $isFirst;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ChangeDefinition
|
||||
#
|
||||
# Changes the information about an existing definition.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> that defines the symbol. Must exist.
|
||||
# type - The new <TopicType> of the definition.
|
||||
# prototype - The new prototype of the definition, if applicable. Undef otherwise.
|
||||
# summary - The new summary of the definition, if applicable. Undef otherwise.
|
||||
#
|
||||
sub ChangeDefinition #(file, type, prototype, summary)
|
||||
{
|
||||
my ($self, $file, $type, $prototype, $summary) = @_;
|
||||
|
||||
if (defined $self->[DEFINITIONS] &&
|
||||
exists $self->[DEFINITIONS]{$file})
|
||||
{
|
||||
$self->[DEFINITIONS]{$file}->SetType($type);
|
||||
$self->[DEFINITIONS]{$file}->SetPrototype($prototype);
|
||||
$self->[DEFINITIONS]{$file}->SetSummary($summary);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteDefinition
|
||||
#
|
||||
# Removes a symbol definition. If the definition served as the global definition, a new one will be selected.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# file - The <FileName> which contains definition to delete.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether that was the only definition, and the symbol is now undefined.
|
||||
#
|
||||
sub DeleteDefinition #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
# If there are no definitions...
|
||||
if (!defined $self->[DEFINITIONS])
|
||||
{ return undef; };
|
||||
|
||||
delete $self->[DEFINITIONS]{$file};
|
||||
|
||||
# If there are no more definitions...
|
||||
if (!scalar keys %{$self->[DEFINITIONS]})
|
||||
{
|
||||
$self->[DEFINITIONS] = undef;
|
||||
|
||||
# If definitions was previously defined, and now is empty, we can safely assume that the global definition was just deleted
|
||||
# without checking it against $file.
|
||||
|
||||
$self->[GLOBAL_DEFINITION] = undef;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# If there are more definitions and the global one was just deleted...
|
||||
elsif ($self->[GLOBAL_DEFINITION] eq $file)
|
||||
{
|
||||
# Which one becomes global is pretty much random.
|
||||
$self->[GLOBAL_DEFINITION] = (keys %{$self->[DEFINITIONS]})[0];
|
||||
return undef;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: AddReference
|
||||
#
|
||||
# Adds a reference that can be interpreted as this symbol. It can be, but not necessarily is.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# referenceString - The string of the reference.
|
||||
# score - The score of this interpretation.
|
||||
#
|
||||
sub AddReference #(referenceString, score)
|
||||
{
|
||||
my ($self, $referenceString, $score) = @_;
|
||||
|
||||
if (!defined $self->[REFERENCES])
|
||||
{ $self->[REFERENCES] = { }; };
|
||||
|
||||
$self->[REFERENCES]{$referenceString} = $score;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteReference
|
||||
#
|
||||
# Deletes a reference that can be interpreted as this symbol.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# referenceString - The string of the reference to delete.
|
||||
#
|
||||
sub DeleteReference #(referenceString)
|
||||
{
|
||||
my ($self, $referenceString) = @_;
|
||||
|
||||
# If there are no definitions...
|
||||
if (!defined $self->[REFERENCES])
|
||||
{ return; };
|
||||
|
||||
delete $self->[REFERENCES]{$referenceString};
|
||||
|
||||
# If there are no more definitions...
|
||||
if (!scalar keys %{$self->[REFERENCES]})
|
||||
{
|
||||
$self->[REFERENCES] = undef;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: DeleteAllReferences
|
||||
#
|
||||
# Removes all references that can be interpreted as this symbol.
|
||||
#
|
||||
sub DeleteAllReferences
|
||||
{
|
||||
$_[0]->[REFERENCES] = undef;
|
||||
};
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Information Functions
|
||||
|
||||
#
|
||||
# Function: IsDefined
|
||||
#
|
||||
# Returns whether the symbol is defined anywhere or not. If it's not, that means it's just a potential interpretation of a
|
||||
# reference.
|
||||
#
|
||||
sub IsDefined
|
||||
{
|
||||
return defined $_[0]->[GLOBAL_DEFINITION];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: IsDefinedIn
|
||||
#
|
||||
# Returns whether the symbol is defined in the passed <FileName>.
|
||||
#
|
||||
sub IsDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
return ($self->IsDefined() && exists $self->[DEFINITIONS]{$file});
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: Definitions
|
||||
#
|
||||
# Returns an array of all the <FileNames> that define this symbol. If none do, will return an empty array.
|
||||
#
|
||||
sub Definitions
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if ($self->IsDefined())
|
||||
{ return keys %{$self->[DEFINITIONS]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GlobalDefinition
|
||||
#
|
||||
# Returns the <FileName> that contains the global definition of this symbol, or undef if the symbol isn't defined.
|
||||
#
|
||||
sub GlobalDefinition
|
||||
{
|
||||
return $_[0]->[GLOBAL_DEFINITION];
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: TypeDefinedIn
|
||||
#
|
||||
# Returns the <TopicType> of the symbol defined in the passed <FileName>, or undef if it's not defined in that file.
|
||||
#
|
||||
sub TypeDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if ($self->IsDefined())
|
||||
{ return $self->[DEFINITIONS]{$file}->Type(); }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GlobalType
|
||||
#
|
||||
# Returns the <TopicType> of the global definition, or undef if the symbol isn't defined.
|
||||
#
|
||||
sub GlobalType
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $globalDefinition = $self->GlobalDefinition();
|
||||
|
||||
if (!defined $globalDefinition)
|
||||
{ return undef; }
|
||||
else
|
||||
{ return $self->[DEFINITIONS]{$globalDefinition}->Type(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: PrototypeDefinedIn
|
||||
#
|
||||
# Returns the prototype of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
|
||||
#
|
||||
sub PrototypeDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if ($self->IsDefined())
|
||||
{ return $self->[DEFINITIONS]{$file}->Prototype(); }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GlobalPrototype
|
||||
#
|
||||
# Returns the prototype of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
|
||||
#
|
||||
sub GlobalPrototype
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $globalDefinition = $self->GlobalDefinition();
|
||||
|
||||
if (!defined $globalDefinition)
|
||||
{ return undef; }
|
||||
else
|
||||
{ return $self->[DEFINITIONS]{$globalDefinition}->Prototype(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SummaryDefinedIn
|
||||
#
|
||||
# Returns the summary of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
|
||||
#
|
||||
sub SummaryDefinedIn #(file)
|
||||
{
|
||||
my ($self, $file) = @_;
|
||||
|
||||
if ($self->IsDefined())
|
||||
{ return $self->[DEFINITIONS]{$file}->Summary(); }
|
||||
else
|
||||
{ return undef; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: GlobalSummary
|
||||
#
|
||||
# Returns the summary of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
|
||||
#
|
||||
sub GlobalSummary
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $globalDefinition = $self->GlobalDefinition();
|
||||
|
||||
if (!defined $globalDefinition)
|
||||
{ return undef; }
|
||||
else
|
||||
{ return $self->[DEFINITIONS]{$globalDefinition}->Summary(); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: HasReferences
|
||||
#
|
||||
# Returns whether the symbol can be interpreted as any references.
|
||||
#
|
||||
sub HasReferences
|
||||
{
|
||||
return defined $_[0]->[REFERENCES];
|
||||
};
|
||||
|
||||
#
|
||||
# Function: References
|
||||
#
|
||||
# Returns an array of all the reference strings that can be interpreted as this symbol. If none, will return an empty array.
|
||||
#
|
||||
sub References
|
||||
{
|
||||
if (defined $_[0]->[REFERENCES])
|
||||
{ return keys %{$_[0]->[REFERENCES]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ReferencesAndScores
|
||||
#
|
||||
# Returns a hash of all the references that can be interpreted as this symbol and their scores. The keys are the reference
|
||||
# strings, and the values are the scores. If none, will return an empty hash.
|
||||
#
|
||||
sub ReferencesAndScores
|
||||
{
|
||||
if (defined $_[0]->[REFERENCES])
|
||||
{ return %{$_[0]->[REFERENCES]}; }
|
||||
else
|
||||
{ return ( ); };
|
||||
};
|
||||
|
||||
1;
|
@ -0,0 +1,97 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::SymbolTable::SymbolDefinition
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class representing a symbol definition. This does not store the definition symbol, class, or file.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::SymbolTable::SymbolDefinition;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||||
#
|
||||
# TYPE - The symbol <TopicType>.
|
||||
# PROTOTYPE - The symbol's prototype, if applicable. Will be undef otherwise.
|
||||
# SUMMARY - The symbol's summary, if applicable. Will be undef otherwise.
|
||||
#
|
||||
use constant TYPE => 0;
|
||||
use constant PROTOTYPE => 1;
|
||||
use constant SUMMARY => 2;
|
||||
# New depends on the order of the constants.
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# type - The symbol <TopicType>.
|
||||
# prototype - The symbol prototype, if applicable. Undef otherwise.
|
||||
# summary - The symbol's summary, if applicable. Undef otherwise.
|
||||
#
|
||||
sub New #(type, prototype, summary)
|
||||
{
|
||||
# This depends on the parameter list being the same as the constant order.
|
||||
|
||||
my $package = shift;
|
||||
|
||||
my $object = [ @_ ];
|
||||
bless $object, $package;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
# Function: Type
|
||||
# Returns the definition's <TopicType>.
|
||||
sub Type
|
||||
{ return $_[0]->[TYPE]; };
|
||||
|
||||
# Function: SetType
|
||||
# Changes the <TopicType>.
|
||||
sub SetType #(type)
|
||||
{ $_[0]->[TYPE] = $_[1]; };
|
||||
|
||||
# Function: Prototype
|
||||
# Returns the definition's prototype, or undef if it doesn't have one.
|
||||
sub Prototype
|
||||
{ return $_[0]->[PROTOTYPE]; };
|
||||
|
||||
# Function: SetPrototype
|
||||
# Changes the prototype.
|
||||
sub SetPrototype #(prototype)
|
||||
{ $_[0]->[PROTOTYPE] = $_[1]; };
|
||||
|
||||
# Function: Summary
|
||||
# Returns the definition's summary, or undef if it doesn't have one.
|
||||
sub Summary
|
||||
{ return $_[0]->[SUMMARY]; };
|
||||
|
||||
# Function: SetSummary
|
||||
# Changes the summary.
|
||||
sub SetSummary #(summary)
|
||||
{ $_[0]->[SUMMARY] = $_[1]; };
|
||||
|
||||
|
||||
1;
|
1321
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics.pm
Executable file
1321
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics.pm
Executable file
File diff suppressed because it is too large
Load Diff
152
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics/Type.pm
Executable file
152
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Topics/Type.pm
Executable file
@ -0,0 +1,152 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Topics::Type
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A class storing information about a <TopicType>.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
|
||||
package NaturalDocs::Topics::Type;
|
||||
|
||||
use NaturalDocs::DefineMembers 'NAME', 'Name()',
|
||||
'PLURAL_NAME', 'PluralName()', 'SetPluralName()',
|
||||
'INDEX', 'Index()', 'SetIndex()',
|
||||
'SCOPE', 'Scope()', 'SetScope()',
|
||||
'PAGE_TITLE_IF_FIRST', 'PageTitleIfFirst()', 'SetPageTitleIfFirst()',
|
||||
'BREAK_LISTS', 'BreakLists()', 'SetBreakLists()',
|
||||
'CLASS_HIERARCHY', 'ClassHierarchy()', 'SetClassHierarchy()',
|
||||
'CAN_GROUP_WITH';
|
||||
|
||||
# Dependency: New() depends on the order of these and that there are no parent classes.
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ('SCOPE_NORMAL', 'SCOPE_START', 'SCOPE_END', 'SCOPE_ALWAYS_GLOBAL');
|
||||
|
||||
#
|
||||
# Constants: Members
|
||||
#
|
||||
# The object is implemented as a blessed arrayref, with the following constants as its indexes.
|
||||
#
|
||||
# NAME - The topic's name.
|
||||
# PLURAL_NAME - The topic's plural name.
|
||||
# INDEX - Whether the topic is indexed.
|
||||
# SCOPE - The topic's <ScopeType>.
|
||||
# PAGE_TITLE_IF_FIRST - Whether the topic becomes the page title if it's first in a file.
|
||||
# BREAK_LISTS - Whether list topics should be broken into individual topics in the output.
|
||||
# CLASS_HIERARCHY - Whether the topic is part of the class hierarchy.
|
||||
# CAN_GROUP_WITH - The existence hashref of <TopicTypes> the type can be grouped with.
|
||||
#
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Types
|
||||
|
||||
|
||||
#
|
||||
# Constants: ScopeType
|
||||
#
|
||||
# The possible values for <Scope()>.
|
||||
#
|
||||
# SCOPE_NORMAL - The topic stays in the current scope without affecting it.
|
||||
# SCOPE_START - The topic starts a scope.
|
||||
# SCOPE_END - The topic ends a scope, returning it to global.
|
||||
# SCOPE_ALWAYS_GLOBAL - The topic is always global, but it doesn't affect the current scope.
|
||||
#
|
||||
use constant SCOPE_NORMAL => 1;
|
||||
use constant SCOPE_START => 2;
|
||||
use constant SCOPE_END => 3;
|
||||
use constant SCOPE_ALWAYS_GLOBAL => 4;
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: New
|
||||
#
|
||||
# Creates and returns a new object.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# name - The topic name.
|
||||
# pluralName - The topic's plural name.
|
||||
# index - Whether the topic is indexed.
|
||||
# scope - The topic's <ScopeType>.
|
||||
# pageTitleIfFirst - Whether the topic becomes the page title if it's the first one in a file.
|
||||
# breakLists - Whether list topics should be broken into individual topics in the output.
|
||||
#
|
||||
sub New #(name, pluralName, index, scope, pageTitleIfFirst, breakLists)
|
||||
{
|
||||
my ($self, @params) = @_;
|
||||
|
||||
# Dependency: Depends on the parameter order matching the member order and that there are no parent classes.
|
||||
|
||||
my $object = [ @params ];
|
||||
bless $object, $self;
|
||||
|
||||
return $object;
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Functions: Accessors
|
||||
#
|
||||
# Name - Returns the topic name.
|
||||
# PluralName - Returns the topic's plural name.
|
||||
# SetPluralName - Replaces the topic's plural name.
|
||||
# Index - Whether the topic is indexed.
|
||||
# SetIndex - Sets whether the topic is indexed.
|
||||
# Scope - Returns the topic's <ScopeType>.
|
||||
# SetScope - Replaces the topic's <ScopeType>.
|
||||
# PageTitleIfFirst - Returns whether the topic becomes the page title if it's first in the file.
|
||||
# SetPageTitleIfFirst - Sets whether the topic becomes the page title if it's first in the file.
|
||||
# BreakLists - Returns whether list topics should be broken into individual topics in the output.
|
||||
# SetBreakLists - Sets whether list topics should be broken into individual topics in the output.
|
||||
# ClassHierarchy - Returns whether the topic is part of the class hierarchy.
|
||||
# SetClassHierarchy - Sets whether the topic is part of the class hierarchy.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Function: CanGroupWith
|
||||
#
|
||||
# Returns whether the type can be grouped with the passed <TopicType>.
|
||||
#
|
||||
sub CanGroupWith #(TopicType type) -> bool
|
||||
{
|
||||
my ($self, $type) = @_;
|
||||
return ( defined $self->[CAN_GROUP_WITH] && exists $self->[CAN_GROUP_WITH]->{$type} );
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: SetCanGroupWith
|
||||
#
|
||||
# Sets the list of <TopicTypes> the type can be grouped with.
|
||||
#
|
||||
sub SetCanGroupWith #(TopicType[] types)
|
||||
{
|
||||
my ($self, $types) = @_;
|
||||
|
||||
$self->[CAN_GROUP_WITH] = { };
|
||||
|
||||
foreach my $type (@$types)
|
||||
{ $self->[CAN_GROUP_WITH]->{$type} = 1; };
|
||||
};
|
||||
|
||||
|
||||
|
||||
1;
|
361
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Version.pm
Executable file
361
lib/ann/fann/docs/NaturalDocs-1.52/Modules/NaturalDocs/Version.pm
Executable file
@ -0,0 +1,361 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Package: NaturalDocs::Version
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# A package for handling version information. What? That's right. Although it should be easy and obvious, version numbers
|
||||
# need to be dealt with in a variety of formats, plus there's compatibility with older releases which handled it differently. I
|
||||
# wanted to centralize the code after it started getting complicated. So there ya go.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# This file is part of Natural Docs, which is Copyright <20> 2003-2010 Greg Valure
|
||||
# Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
|
||||
# Refer to License.txt for the complete details
|
||||
|
||||
use strict;
|
||||
use integer;
|
||||
|
||||
package NaturalDocs::Version;
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Functions
|
||||
|
||||
|
||||
#
|
||||
# Function: ToString
|
||||
#
|
||||
# Converts a <VersionInt> to a string.
|
||||
#
|
||||
sub ToString #(VersionInt version) => string
|
||||
{
|
||||
my ($self, $version) = @_;
|
||||
|
||||
my ($major, $minor, $month, $day, $year) = $self->ToValues($version);
|
||||
|
||||
if ($minor % 10 == 0)
|
||||
{ $minor /= 10; };
|
||||
|
||||
if ($day)
|
||||
{ return sprintf('Development Release %02d-%02d-%d (%d.%d base)', $month, $day, $year, $major, $minor); }
|
||||
else
|
||||
{ return $major . '.' . $minor; };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromString
|
||||
#
|
||||
# Converts a version string to a <VersionInt>.
|
||||
#
|
||||
sub FromString #(string string) => VersionInt
|
||||
{
|
||||
my ($self, $string) = @_;
|
||||
|
||||
if ($string eq '1')
|
||||
{
|
||||
return $self->FromValues(0, 91, 0, 0, 0); # 0.91
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($major, $minor, $month, $day, $year);
|
||||
|
||||
if ($string =~ /^(\d{1,2})\.(\d{1,2})$/)
|
||||
{
|
||||
($major, $minor) = ($1, $2);
|
||||
($month, $day, $year) = (0, 0, 0);
|
||||
}
|
||||
elsif ($string =~ /^Development Release (\d{1,2})-(\d{1,2})-(\d\d\d\d) \((\d{1,2})\.(\d{1,2}) base\)$/)
|
||||
{
|
||||
($month, $day, $year, $major, $minor) = ($1, $2, $3, $4, $5);
|
||||
|
||||
# We have to do sanity checking because these can come from user-editable text files. The version numbers should
|
||||
# already be constrained simply by being forced to have only two digits.
|
||||
|
||||
if ($month > 12 || $month < 1 || $day > 31 || $day < 1 || $year > 2255 || $year < 2000)
|
||||
{ die 'The version string ' . $string . " doesn't have a valid date.\n"; };
|
||||
}
|
||||
else
|
||||
{
|
||||
die 'The version string ' . $string . " isn't in a recognized format.\n";
|
||||
};
|
||||
|
||||
if (length $minor == 1)
|
||||
{ $minor *= 10; };
|
||||
|
||||
return $self->FromValues($major, $minor, $month, $day, $year);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToTextFile
|
||||
#
|
||||
# Writes a <VersionInt> to a text file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The handle of the file to write it to. It should be at the correct location.
|
||||
# version - The <VersionInt> to write.
|
||||
#
|
||||
sub ToTextFile #(handle fileHandle, VersionInt version)
|
||||
{
|
||||
my ($self, $fileHandle, $version) = @_;
|
||||
|
||||
print $fileHandle $self->ToString($version) . "\n";
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToBinaryFile
|
||||
#
|
||||
# Writes a <VersionInt> to a binary file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The handle of the file to write it to. It should be at the correct location.
|
||||
# version - The <VersionInt> to write.
|
||||
#
|
||||
sub ToBinaryFile #(handle fileHandle, VersionInt version)
|
||||
{
|
||||
my ($self, $fileHandle, $version) = @_;
|
||||
|
||||
my ($major, $minor, $month, $day, $year) = $self->ToValues($version);
|
||||
|
||||
# 1.35 development releases are encoded as 1.36. Everything else is literal.
|
||||
if ($day && $major == 1 && $minor == 35)
|
||||
{ $minor = 36; };
|
||||
|
||||
print $fileHandle pack('CC', $major, $minor);
|
||||
|
||||
# Date fields didn't exist with 1.35 stable and earlier. 1.35 development releases are encoded as 1.36, so this works.
|
||||
if ($major > 1 || ($major == 1 && $minor > 35))
|
||||
{
|
||||
if ($day)
|
||||
{ $year -= 2000; };
|
||||
|
||||
print $fileHandle pack('CCC', $month, $day, $year);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromBinaryFile
|
||||
#
|
||||
# Retrieves a <VersionInt> from a binary file.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileHandle - The handle of the file to read it from. It should be at the correct location.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The <VersionInt>.
|
||||
#
|
||||
sub FromBinaryFile #(handle fileHandle) => VersionInt
|
||||
{
|
||||
my ($self, $fileHandle) = @_;
|
||||
|
||||
my ($major, $minor, $month, $day, $year);
|
||||
|
||||
my $raw;
|
||||
read($fileHandle, $raw, 2);
|
||||
|
||||
($major, $minor) = unpack('CC', $raw);
|
||||
|
||||
# 1.35 stable is the last release without the date fields. 1.35 development releases are encoded as 1.36, so this works.
|
||||
if ($major > 1 || ($major == 1 && $minor > 35))
|
||||
{
|
||||
read($fileHandle, $raw, 3);
|
||||
($month, $day, $year) = unpack('CCC', $raw);
|
||||
|
||||
if ($day)
|
||||
{ $year += 2000; };
|
||||
}
|
||||
else
|
||||
{ ($month, $day, $year) = (0, 0, 0); };
|
||||
|
||||
# Fix the 1.35 development release special encoding.
|
||||
if ($major == 1 && $minor == 36)
|
||||
{ $minor = 35; };
|
||||
|
||||
|
||||
return $self->FromValues($major, $minor, $month, $day, $year);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: ToValues
|
||||
#
|
||||
# Converts a <VersionInt> to the array ( major, minor, month, day, year ). The minor version will be in two digit form, so x.2
|
||||
# will return 20. The date fields will be zero for stable releases.
|
||||
#
|
||||
sub ToValues #(VersionInt version) => ( int, int, int, int, int )
|
||||
{
|
||||
my ($self, $version) = @_;
|
||||
|
||||
my $major = ($version & 0x00003F80) >> 7;
|
||||
my $minor = ($version & 0x0000007F);
|
||||
my $month = ($version & 0x00780000) >> 19;
|
||||
my $day = ($version & 0x0007C000) >> 14;
|
||||
my $year = ($version & 0x7F800000) >> 23;
|
||||
|
||||
if ($year)
|
||||
{ $year += 2000; };
|
||||
|
||||
return ( $major, $minor, $month, $day, $year );
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: FromValues
|
||||
#
|
||||
# Returns a <VersionInt> created from the passed values.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# major - The major version number. For development releases, it should be the stable version it's based off of.
|
||||
# minor - The minor version number. It should always be two digits, so x.2 should pass 20. For development
|
||||
# releases, it should be the stable version it's based off of.
|
||||
# month - The numeric month of the development release. For stable releases it should be zero.
|
||||
# day - The day of the development release. For stable releases it should be zero.
|
||||
# year - The year of the development release. For stable releases it should be zero.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# The <VersionInt>.
|
||||
#
|
||||
sub FromValues #(int major, int minor, int month, int day, int year) => VersionInt
|
||||
{
|
||||
my ($self, $major, $minor, $month, $day, $year) = @_;
|
||||
|
||||
if ($day)
|
||||
{ $year -= 2000; };
|
||||
|
||||
return ($major << 7) + ($minor) + ($month << 19) + ($day << 14) + ($year << 23);
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: CheckFileFormat
|
||||
#
|
||||
# Checks if a file's format is compatible with the current release.
|
||||
#
|
||||
# - If the application is a development release or the file is from one, this only returns true if they are from the exact same
|
||||
# development release.
|
||||
# - If neither of them are development releases, this only returns true if the file is from a release between the minimum specified
|
||||
# and the current version. If there's no minimum it just checks that it's below the current version.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# fileVersion - The <VersionInt> of the file format.
|
||||
# minimumVersion - The minimum <VersionInt> required of the file format. May be undef.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# Whether the file's format is compatible per the above rules.
|
||||
#
|
||||
sub CheckFileFormat #(VersionInt fileVersion, optional VersionInt minimumVersion) => bool
|
||||
{
|
||||
my ($self, $fileVersion, $minimumVersion) = @_;
|
||||
|
||||
my $appVersion = NaturalDocs::Settings->AppVersion();
|
||||
|
||||
if ($self->IsDevelopmentRelease($appVersion) || $self->IsDevelopmentRelease($fileVersion))
|
||||
{ return ($appVersion == $fileVersion); }
|
||||
elsif ($minimumVersion && $fileVersion < $minimumVersion)
|
||||
{ return 0; }
|
||||
else
|
||||
{ return ($fileVersion <= $appVersion); };
|
||||
};
|
||||
|
||||
|
||||
#
|
||||
# Function: IsDevelopmentRelease
|
||||
#
|
||||
# Returns whether the passed <VersionInt> is for a development release.
|
||||
#
|
||||
sub IsDevelopmentRelease #(VersionInt version) => bool
|
||||
{
|
||||
my ($self, $version) = @_;
|
||||
|
||||
# Return if any of the date fields are set.
|
||||
return ($version & 0x7FFFC000);
|
||||
};
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Group: Implementation
|
||||
|
||||
#
|
||||
# About: String Format
|
||||
#
|
||||
# Full Releases:
|
||||
#
|
||||
# Full releases are in the common major.minor format. Either part can be up to two digits. The minor version is interpreted
|
||||
# as decimal places, so 1.3 > 1.22. There are no leading or trailing zeroes.
|
||||
#
|
||||
# Development Releases:
|
||||
#
|
||||
# Development releases are in the format "Development Release mm-dd-yyyy (vv.vv base)" where vv.vv is the version
|
||||
# number of the full release it's based off of. The month and day will have leading zeroes where applicable. Example:
|
||||
# "Development Release 07-09-2006 (1.35 base)".
|
||||
#
|
||||
# 0.91 and Earlier:
|
||||
#
|
||||
# Text files from releases prior to 0.95 had a separate file format version number that was used instead of the application
|
||||
# version. These were never changed between 0.85 and 0.91, so they are simply "1". Text version numbers that are "1"
|
||||
# instead of "1.0" will be interpreted as 0.91.
|
||||
#
|
||||
|
||||
#
|
||||
# About: Integer Format
|
||||
#
|
||||
# <VersionInts> are 32-bit values with the bit distribution below.
|
||||
#
|
||||
# > s yyyyyyyy mmmm ddddd vvvvvvv xxxxxxx
|
||||
# > [syyy|yyyy] [ymmm|mddd] [ddvv|vvvv] [vxxx|xxxx]
|
||||
#
|
||||
# s - The sign bit. Always zero, so it's always interpreted as positive.
|
||||
# y - The year bits if it's a development release, zero otherwise. 2000 is added to the value, so the range is from 2000 to 2255.
|
||||
# m - The month bits if it's a development release, zero otherwise.
|
||||
# d - The day bits if it's a development release, zero otherwise.
|
||||
# v - The major version bits. For development releases, it's the last stable version it was based off of.
|
||||
# x - The minor version bits. It's always stored as two decimals, so x.2 would store 20 here. For development releases, it's the
|
||||
# last stable version it was based off of.
|
||||
#
|
||||
# It's stored with the development release date at a higher significance than the version because we want a stable release to
|
||||
# always treat a development release as higher than itself, and thus not attempt to read any of the data files. I'm not tracking
|
||||
# data file formats at the development release level.
|
||||
#
|
||||
|
||||
#
|
||||
# About: Binary File Format
|
||||
#
|
||||
# Current:
|
||||
#
|
||||
# Five 8-bit unsigned values, appearing major, minor, month, day, year. Minor is always stored with two digits, so x.2 would
|
||||
# store 20. Year is stored minus 2000, so 2006 is stored 6. Stable releases store zero for all the date fields.
|
||||
#
|
||||
# 1.35 Development Releases:
|
||||
#
|
||||
# 1.35-based development releases are stored the same as current releases, but with 1.36 as the version number. This is
|
||||
# done so previous versions of Natural Docs that didn't include the date fields would still know it's a higher version. There is
|
||||
# no actual 1.36 release.
|
||||
#
|
||||
# 1.35 and Earlier:
|
||||
#
|
||||
# Two 8-bit unsigned values, appearing major then minor. Minor is always stored with two digits, so x.2 would store 20.
|
||||
#
|
||||
|
||||
#
|
||||
# About: Text File Format
|
||||
#
|
||||
# In text files, versions are the <String Format> followed by a native line break.
|
||||
#
|
||||
|
||||
|
||||
1;
|
Reference in New Issue
Block a user