mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
335 lines
10 KiB
Perl
335 lines
10 KiB
Perl
|
###############################################################################
|
||
|
#
|
||
|
# Package: NaturalDocs::ReferenceString
|
||
|
#
|
||
|
###############################################################################
|
||
|
#
|
||
|
# A package to manage <ReferenceString> handling throughout the program.
|
||
|
#
|
||
|
###############################################################################
|
||
|
|
||
|
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
||
|
# Natural Docs is licensed under the GPL
|
||
|
|
||
|
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' );
|
||
|
|
||
|
|
||
|
#
|
||
|
# 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]
|
||
|
# > [AString16: 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);
|
||
|
|
||
|
# [AString16: language]
|
||
|
|
||
|
print $fileHandle pack('nA*', length $language, $language);
|
||
|
|
||
|
# [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; };
|
||
|
|
||
|
|
||
|
# [AString16: language]
|
||
|
|
||
|
read($fileHandle, $raw, 2);
|
||
|
my $languageLength = unpack('n', $raw);
|
||
|
|
||
|
my $language;
|
||
|
read($fileHandle, $language, $languageLength);
|
||
|
|
||
|
|
||
|
# [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;
|