my $VERSION = 2.1;
my $isMacOS;
my $pathSeparator;
my $specifiedOutputDir;
my $export;
my $debugging;
my $testingExport = 0;
my $printVersion;
my $quietLevel;
my $xml_output;
my $headerdoc_strip;
my $regenerate_headers;
my $write_control_file;
my $lang = "C";
my $scriptDir;
my $lookupTableDirName;
my $lookupTableDir;
my $dbLookupTables;
my $functionFilename;
my $typesFilename;
my $enumsFilename;
my $masterTOCName;
my @inputFiles;
my @ignorePrefixes = ();
my @perHeaderIgnorePrefixes = ();
my $reprocess_input = 0;
my $functionGroup = "";
$HeaderDoc::outerNamesOnly = 0;
$HeaderDoc::globalGroup = "";
my @headerObjects; my @categoryObjects; my %objCClassNameToObject;
my @classObjects;
$| = 1;
my $modulesPath;
BEGIN {
use FindBin qw ($Bin);
use Cwd;
use Getopt::Std;
use File::Find;
use lib '/Library/Perl/TechPubs'; use lib '/AppleInternal/Library/Perl';
my %options = ();
$lookupTableDirName = "LookupTables";
$functionFilename = "functions.tab";;
$typesFilename = "types.tab";
$enumsFilename = "enumConstants.tab";
$scriptDir = cwd();
$HeaderDoc::force_parameter_tagging = 0;
$HeaderDoc::use_styles = 0;
$HeaderDoc::ignore_apiuid_errors = 0;
$HeaderDoc::maxDecLen = 60;
if ($^O =~ /MacOS/i) {
$pathSeparator = ":";
$isMacOS = 1;
($modulesPath = $FindBin::Bin) =~ s/([^:]*):$/$1/;
} else {
$pathSeparator = "/";
$isMacOS = 0;
}
$modulesPath = "$FindBin::Bin"."$pathSeparator"."Modules";
foreach (qw(Mac::Files)) {
$MOD_AVAIL{$_} = eval "use $_; 1";
}
$HeaderDoc::twig_available = 0;
foreach my $path (@INC) {
my $name = $path.$pathSeparator."XML".$pathSeparator."Twig.pm";
if (-f $name) {
$HeaderDoc::twig_available = 1;
}
}
if ($HeaderDoc::twig_available) {
}
&getopts("CHOSXdho:qrstuvx", \%options);
if ($options{v}) {
print "Getting version information for all modules. Please wait...\n";
$printVersion = 1;
return;
}
if ($options{r}) {
if ($HeaderDoc::twig_available) {
print "Regenerating headers.\n";
} else {
warn "***********************************************************************\n";
warn "* Headerdoc comment regeneration from XML requires XML::Parser *\n";
warn "* and XML::Twig, available from CPAN. Visit *\n";
warn "* *\n";
warn "* http://www.cpan.org *\n";
warn "* *\n";
warn "* for more information. *\n";
warn "***********************************************************************\n";
exit -1;
}
$regenerate_headers = 1;
} else {
$regenerate_headers = 0;
}
if ($options{S}) {
$HeaderDoc::IncludeSuper = 1;
} else {
$HeaderDoc::IncludeSuper = 0;
}
if ($options{C}) {
$HeaderDoc::ClassAsComposite = 1;
} else {
$HeaderDoc::ClassAsComposite = 0;
}
if ($options{s}) {
$headerdoc_strip = 1;
} else {
$headerdoc_strip = 0;
}
if ($options{h}) {
$write_control_file = "1";
} else {
$write_control_file = "0";
}
if ($options{u}) {
$HeaderDoc::sort_entries = 0;
} else {
$HeaderDoc::sort_entries = 1;
}
if ($options{H}) {
$HeaderDoc::insert_header = 1;
} else {
$HeaderDoc::insert_header = 0;
}
if ($options{q}) {
$quietLevel = "1";
} else {
$quietLevel = "0";
}
if ($options{t}) {
if (!$quietLevel) {
print "Forcing strict parameter tagging.\n";
}
$HeaderDoc::force_parameter_tagging = 1;
}
if ($options{O}) {
$HeaderDoc::outerNamesOnly = 1;
} else {
$HeaderDoc::outerNamesOnly = 0;
}
if ($options{d}) {
print "\tDebugging on...\n\n";
$debugging = 1;
}
if ($options{o}) {
$specifiedOutputDir = $options{o};
if (! -e $specifiedOutputDir) {
unless (mkdir ("$specifiedOutputDir", 0777)) {
die "Error: $specifiedOutputDir does not exist. Exiting. \n$!\n";
}
} elsif (! -d $specifiedOutputDir) {
die "Error: $specifiedOutputDir is not a directory. Exiting.\n$!\n";
} elsif (! -w $specifiedOutputDir) {
die "Error: Output directory $specifiedOutputDir is not writable. Exiting.\n$!\n";
}
if ($quietLevel eq "0") {
print "\nDocumentation will be written to $specifiedOutputDir\n";
}
}
$lookupTableDir = "$scriptDir$pathSeparator$lookupTableDirName";
if (($options{x}) || ($testingExport)) {
if ((-e "$lookupTableDir$pathSeparator$functionFilename") && (-e "$lookupTableDir$pathSeparator$typesFilename")) {
print "\nWill write database files to an Export directory within each top-level HTML directory.\n\n";
$export = 1;
} else {
print "\nLookup table files not available. Cannot export data.\n";
$export = 0;
$testingExport = 0;
}
}
if ($quietLevel eq "0") {
if ($options{X}) {
print "XML output mode.\n";
$xml_output = 1;
} else {
print "HTML output mode.\n";
$xml_output = 0;
}
}
if (($ my $inputDir = $ARGV[0];
if ($inputDir =~ /$pathSeparator$/) {
$inputDir =~ s|(.*)$pathSeparator$|$1|; }
if ($^O =~ /MacOS/i) {
find(\&getHeaders, $inputDir);
} else {
&find({wanted => \&getHeaders, follow => 1}, $inputDir);
}
} else {
print "Will process one or more individual files.\n" if ($debugging);
foreach my $singleFile (@ARGV) {
if (-f $singleFile) {
push(@inputFiles, $singleFile);
}
}
}
unless (@inputFiles) {
print "No valid input files specified. \n\n";
if ($isMacOS) {
die "\tTo use HeaderDoc, drop a header file or folder of header files on this application.\n\n";
} else {
die "\tUsage: headerdoc2html [-dq] [-o <output directory>] <input file(s) or directory>.\n\n";
}
}
sub getHeaders {
my $filePath = $File::Find::name;
my $fileName = $_;
if ($fileName =~ /\.(c|h|i|hdoc|php|php\d|class|pas|p|java|jsp|js|jscript|html|shtml|pl|csh|sh|defs)$/) {
push(@inputFiles, $filePath);
}
}
}
use strict;
use File::Copy;
use lib $modulesPath;
use HeaderDoc::DBLookup;
use HeaderDoc::Utilities qw(findRelativePath safeName getAPINameAndDisc printArray linesFromFile
printHash updateHashFromConfigFiles getHashFromConfigFile quote parseTokens);
use HeaderDoc::BlockParse qw(blockParse);
use HeaderDoc::Header;
use HeaderDoc::ClassArray;
use HeaderDoc::CPPClass;
use HeaderDoc::ObjCClass;
use HeaderDoc::ObjCProtocol;
use HeaderDoc::ObjCCategory;
use HeaderDoc::Function;
use HeaderDoc::Method;
use HeaderDoc::Typedef;
use HeaderDoc::Struct;
use HeaderDoc::Constant;
use HeaderDoc::Var;
use HeaderDoc::PDefine;
use HeaderDoc::Enum;
use HeaderDoc::MinorAPIElement;
use HeaderDoc::ParseTree;
my $localConfigFileName = "headerDoc2HTML.config";
my $preferencesConfigFileName = "com.apple.headerDoc2HTML.config";
my $homeDir;
my $usersPreferencesPath;
if ($^O =~ /MacOS/i) {
eval
{
require "FindFolder.pl";
$homeDir = MacPerl::FindFolder("D"); $usersPreferencesPath = MacPerl::FindFolder("P"); };
if ($@) {
import Mac::Files;
$homeDir = Mac::Files::FindFolder(kOnSystemDisk(), kDesktopFolderType());
$usersPreferencesPath = Mac::Files::FindFolder(kOnSystemDisk(), kPreferencesFolderType());
}
} else {
$homeDir = (getpwuid($<))[7];
$usersPreferencesPath = $homeDir.$pathSeparator."Library".$pathSeparator."Preferences";
}
my @configFiles = ($usersPreferencesPath.$pathSeparator.$preferencesConfigFileName, $Bin.$pathSeparator.$localConfigFileName);
my %config = (
copyrightOwner => "",
defaultFrameName => "index.html",
compositePageName => "CompositePage.html",
masterTOCName => "MasterTOC.html",
apiUIDPrefix => "apple_ref",
ignorePrefixes => "",
htmlHeader => "",
dateFormat => "",
textStyle => "",
commentStyle => "",
preprocessorStyle => "",
funcNameStyle => "",
stringStyle => "",
charStyle => "",
numberStyle => "",
keywordStyle => "",
typeStyle => "",
paramStyle => "",
varStyle => ""
);
%config = &updateHashFromConfigFiles(\%config,\@configFiles);
if (defined $config{"ignorePrefixes"}) {
my $localDebug = 0;
my @prefixlist = split(/\|/, $config{"ignorePrefixes"});
foreach my $prefix (@prefixlist) {
print "ignoring $prefix\n" if ($localDebug);
push(@ignorePrefixes, $prefix);
}
}
if (defined $config{"copyrightOwner"}) {
HeaderDoc::APIOwner->copyrightOwner($config{"copyrightOwner"});
}
if (defined $config{"defaultFrameName"}) {
HeaderDoc::APIOwner->defaultFrameName($config{"defaultFrameName"});
}
if (defined $config{"compositePageName"}) {
HeaderDoc::APIOwner->compositePageName($config{"compositePageName"});
}
if (defined $config{"apiUIDPrefix"}) {
HeaderDoc::APIOwner->apiUIDPrefix($config{"apiUIDPrefix"});
}
if (defined $config{"htmlHeader"}) {
HeaderDoc::APIOwner->htmlHeader($config{"htmlHeader"});
}
my $oldRecSep = $/;
undef $/;
if (defined $config{"htmlHeaderFile"}) {
my $basename = $config{"htmlHeaderFile"};
my @htmlHeaderFiles = ($Bin.$pathSeparator.$basename, $usersPreferencesPath.$pathSeparator.$basename, $basename);
foreach my $filename (@htmlHeaderFiles) {
if (open(HTMLHEADERFILE, "<$filename")) {
my $headerString = <HTMLHEADERFILE>;
close(HTMLHEADERFILE);
HeaderDoc::APIOwner->htmlHeader($headerString);
}
}
}
$/ = $oldRecSep;
if (defined $config{"dateFormat"}) {
$HeaderDoc::datefmt = $config{"dateFormat"};
}
HeaderDoc::APIOwner->fix_date();
if (defined $config{"textStyle"}) {
HeaderDoc::APIOwner->setStyle("text", $config{"textStyle"});
}
if (defined $config{"commentStyle"}) {
HeaderDoc::APIOwner->setStyle("comment", $config{"commentStyle"});
}
if (defined $config{"preprocessorStyle"}) {
HeaderDoc::APIOwner->setStyle("preprocessor", $config{"preprocessorStyle"});
}
if (defined $config{"funcNameStyle"}) {
HeaderDoc::APIOwner->setStyle("function", $config{"funcNameStyle"});
}
if (defined $config{"stringStyle"}) {
HeaderDoc::APIOwner->setStyle("string", $config{"stringStyle"});
}
if (defined $config{"charStyle"}) {
HeaderDoc::APIOwner->setStyle("char", $config{"charStyle"});
}
if (defined $config{"numberStyle"}) {
HeaderDoc::APIOwner->setStyle("number", $config{"numberStyle"});
}
if (defined $config{"keywordStyle"}) {
HeaderDoc::APIOwner->setStyle("keyword", $config{"keywordStyle"});
}
if (defined $config{"typeStyle"}) {
HeaderDoc::APIOwner->setStyle("type", $config{"typeStyle"});
}
if (defined $config{"paramStyle"}) {
HeaderDoc::APIOwner->setStyle("param", $config{"paramStyle"});
}
if (defined $config{"varStyle"}) {
HeaderDoc::APIOwner->setStyle("var", $config{"varStyle"});
}
if ($printVersion) {
&printVersionInfo();
exit;
}
if ($export || $testingExport) {
HeaderDoc::DBLookup->loadUsingFolderAndFiles($lookupTableDir, $functionFilename, $typesFilename, $enumsFilename);
}
my $inHeader = 0;
my $inJavaSource = 0;
my $inShellScript = 0;
my $inPerlScript = 0;
my $inPHPScript = 0;
my $inCPPHeader = 0;
my $inOCCHeader = 0;
my $inClass = 0; my $inInterface = 0;
my $inFunction = 0;
my $inFunctionGroup = 0;
my $inGroup = 0;
my $inTypedef = 0;
my $inUnknown = 0;
my $inStruct = 0;
my $inUnion = 0;
my $inConstant = 0;
my $inVar = 0;
my $inPDefine = 0;
my $inEnum = 0;
my $inMethod = 0;
my $headerObject; my $rootFileName;
if (!$quietLevel) {
print "======= Parsing Input Files =======\n";
}
my $methods_with_new_parser = 1;
foreach my $inputFile (@inputFiles) {
my $constantObj;
my $enumObj;
my $funcObj;
my $methObj;
my $pDefineObj;
my $structObj;
my $curObj;
my $varObj;
my $cppAccessControlState = "protected:"; my $objcAccessControlState = "private:";
my @path = split (/$pathSeparator/, $inputFile);
my $filename = pop (@path);
my $sublang = "";
if ($quietLevel eq "0") {
if ($headerdoc_strip) {
print "\nStripping $filename\n";
} elsif ($regenerate_headers) {
print "\nRegenerating $filename\n";
} else {
print "\nProcessing $filename\n";
}
}
@perHeaderIgnorePrefixes = ();
$reprocess_input = 0;
my $headerDir = join("$pathSeparator", @path);
($rootFileName = $filename) =~ s/\.(c|h|i|hdoc|php|php\d|class|pas|p|java|jsp|js|jscript|html|shtml|pl|csh|sh|defs)$//;
if ($filename =~ /\.(php|php\d|class)$/) {
$lang = "php";
$sublang = "php";
} elsif ($filename =~ /\.(c|C|cpp)$/) {
$lang = "Csource";
$sublang = "Csource";
} elsif ($filename =~ /\.(s|d|)html$/) {
$lang = "java";
$sublang = "java";
} elsif ($filename =~ /\.j(ava|s|sp|script)$/) {
$lang = "java";
$sublang = "javascript";
} elsif ($filename =~ /\.p(as|)$/) {
$lang = "pascal";
$sublang = "pascal";
} elsif ($filename =~ /\.pl$/) {
$lang = "perl";
$sublang = "perl";
} elsif ($filename =~ /\.(c|)sh$/) {
$lang = "shell";
$sublang = "shell";
} else {
$lang = "C";
$sublang = "C";
}
$HeaderDoc::lang = $lang;
$HeaderDoc::sublang = $sublang;
if ($filename =~ /\.defs/) {
$HeaderDoc::sublang = "MIG";
}
my $rootOutputDir;
if (length ($specifiedOutputDir)) {
$rootOutputDir ="$specifiedOutputDir$pathSeparator$rootFileName";
} elsif (@path) {
$rootOutputDir ="$headerDir$pathSeparator$rootFileName";
} else {
$rootOutputDir = $rootFileName;
}
my @rawInputLines = &linesFromFile($inputFile);
my @cookedInputLines;
my $localDebug = 0;
foreach my $line (@rawInputLines) {
foreach my $prefix (@ignorePrefixes) {
if ($line =~ s/^\s*$prefix\s*//g) {
print "ignored $prefix\n" if ($localDebug);
}
}
push(@cookedInputLines, $line);
}
@rawInputLines = @cookedInputLines;
REDO:
print "REDO" if ($debugging);
my @headerDocCommentLines = grep(/^\s*\/\*\!/, @rawInputLines);
if ((!@headerDocCommentLines) && ($lang eq "java")) {
@headerDocCommentLines = grep(/^\s*\/\*\*/, @rawInputLines);
}
if ((!@headerDocCommentLines) && ($lang eq "perl" || $lang eq "shell")) {
@headerDocCommentLines = grep(/^\s*\ }
if ((!@headerDocCommentLines) && ($lang eq "pascal")) {
@headerDocCommentLines = grep(/^\s*\{\!/, @rawInputLines);
}
if (!@headerDocCommentLines) {
if ($quietLevel eq "0") {
print " Skipping. No HeaderDoc comments found.\n";
}
next;
}
$headerObject = HeaderDoc::Header->new();
$headerObject->linenum(0);
$headerObject->apiOwner($headerObject);
$HeaderDoc::headerObject = $headerObject;
if ($quietLevel eq "0") {
if ($xml_output) {
$headerObject->outputformat("hdxml");
} else {
$headerObject->outputformat("html");
}
}
$headerObject->outputDir($rootOutputDir);
$headerObject->name($filename);
$headerObject->filename($filename);
my $fullpath=cwd()."/$inputFile";
$headerObject->fullpath($fullpath);
my @lineArrays = &getLineArrays(\@rawInputLines);
my $localDebug = 0;
my $linenumdebug = 0;
if ($headerdoc_strip) {
strip($filename, $rootOutputDir, \@rawInputLines);
print "done.\n" if ($quietLevel eq "0");
next;
}
if ($regenerate_headers) {
HeaderDoc::Regen->regenerate($inputFile, $rootOutputDir);
print "done.\n" if ($quietLevel eq "0");
next;
}
foreach my $arrayRef (@lineArrays) {
my $blockOffset = 0;
my @inputLines = @$arrayRef;
my $apiOwner = $headerObject; $HeaderDoc::currentClass = $apiOwner;
print "inHeader\n" if ($localDebug);
my $inputCounter = 0;
my $ctdebug = 0;
my $classType = "unknown";
print "CLASS TYPE CHANGED TO $classType\n" if ($ctdebug);
while ($inputCounter <= $ my $line = "";
print "Input line number: $inputCounter\n" if ($localDebug);
print "last line ".$inputLines[$inputCounter-1]."\n" if ($localDebug);
print "next line ".$inputLines[$inputCounter]."\n" if ($localDebug);
if ($inputLines[$inputCounter] =~ /^\s*(public|private|protected)/) {
$cppAccessControlState = $&;
if ($inputLines[$inputCounter] =~ /^\s*(public|private|protected)\s*:/) {
$cppAccessControlState =~ s/^\s+//;
$cppAccessControlState =~ s/\s*:\s*$/$1/s;
$cppAccessControlState = "$cppAccessControlState:";
}
}
if ($inputLines[$inputCounter] =~ /^\s*(\@public|\@private|\@protected)/) {
$objcAccessControlState = $&;
if ($inputLines[$inputCounter] =~ /^\s*(\@public|\@private|\@protected)\s+/) {
$objcAccessControlState =~ s/^\s+//;
$objcAccessControlState =~ s/\s*:\s*$/$1/s;
$objcAccessControlState = "$objcAccessControlState:";
}
}
if (($lang ne "pascal" && (
($inputLines[$inputCounter] =~ /^\s*\/\*\!/) ||
(($lang eq "perl" || $lang eq "shell") && ($inputLines[$inputCounter] =~ /^\s*\ (($lang eq "java") && ($inputLines[$inputCounter] =~ /^\s*\/\*\*/)))) ||
(($lang eq "pascal") && ($inputLines[$inputCounter] =~ s/^\s*\{!/\/\*!/s))) { my $newlinecount = 0;
if (($lang ne "pascal" && ($inputLines[$inputCounter] =~ /\s*\*\//)) ||
($lang eq "pascal" && ($inputLines[$inputCounter] =~ s/\s*\}/\*\//s))) { # closing comment marker on same line
my $linecopy = $inputLines[$inputCounter];
$newlinecount = ($linecopy =~ tr/\n//);
$blockOffset += $newlinecount - 1;
print "NEWLINECOUNT: $newlinecount\n" if ($linenumdebug);
print "BLOCKOFFSET: $blockOffset\n" if ($linenumdebug);
$line .= $inputLines[$inputCounter++];
if (!emptyHDok($line)) {
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "HeaderDoc comment", "1");
}
print "Input line number: $inputCounter\n" if ($localDebug);
print "next line ".$inputLines[$inputCounter]."\n" if ($localDebug);
} else { my $in_textblock = 0; my $in_pre = 0;
do {
my $templine = $inputLines[$inputCounter];
while ($templine =~ s/\@textblock//i) { $in_textblock++; }
while ($templine =~ s/\@\/textblock//i) { $in_textblock--; }
while ($templine =~ s/<pre>//i) { $in_pre++; print "IN PRE\n" if ($localDebug);}
while ($templine =~ s/<\/pre>//i) { $in_pre--; print "OUT OF PRE\n" if ($localDebug);}
if (!$in_textblock && !$in_pre) {
$inputLines[$inputCounter] =~ s/^[\t ]*[*]?[\t ]+(.*)$/$1/; }
my $newline = $inputLines[$inputCounter++];
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "HeaderDoc comment", "2");
$newline =~ s/^ \*//;
if ($lang eq "perl" || $lang eq "shell") {
$newline =~ s/^\s*\ }
$line .= $newline;
print "Input line number: $inputCounter\n" if ($localDebug);
print "next line ".$inputLines[$inputCounter]."\n" if ($localDebug);
} while ((($lang eq "pascal" && ($inputLines[$inputCounter] !~ /\}/)) ||($lang ne "pascal" && ($inputLines[$inputCounter] !~ s/\*\//\*\//s))) && ($inputCounter <= $#inputLines));
my $newline = $inputLines[$inputCounter++];
if (!emptyHDok($line)) {
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "HeaderDoc comment", "3");
}
if ($lang eq "perl" || $lang eq "shell") {
$newline =~ s/^\s*\ }
if ($newline !~ /^ \*\//) {
$newline =~ s/^ \*//;
}
$line .= $newline; print "Input line number: $inputCounter\n" if ($localDebug);
print "last line ".$inputLines[$inputCounter-1]."\n" if ($localDebug);
print "next line ".$inputLines[$inputCounter]."\n" if ($localDebug);
}
if (($lang eq "perl" || $lang eq "shell") && ($line =~ /^\s*\ $line =~ s/^\s*\ }
if (($lang eq "java") && ($line =~ /^\s*\/\*\*/)) {
$line =~ s/^\s*\/\*\*/\/\*\!/;
}
$line =~ s/^\s+//; # trim leading whitespace
$line =~ s/^(.*)\*\/\s*$/$1/s;
SWITCH: { ($line =~ /^\/\*!\s+\@header\s*/i) && do {$inHeader = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@framework\s*/i) && do {$inHeader = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@template\s*/i) && do {$inClass = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@interface\s*/i) && do {$inClass = 1; $inInterface = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@class\s*/i) && do {$inClass = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@protocol\s*/i) && do {$inClass = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@category\s*/i) && do {$inClass = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*c\+\+\s*/i) && do {$inCPPHeader = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*objc\s*/i) && do {$inOCCHeader = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*perl\s*/i) && do {$inPerlScript = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*shell\s*/i) && do {$inShellScript = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*php\s*/i) && do {$inPHPScript = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*java\s*/i) && do {$inJavaSource = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@language\s+.*javascript\s*/i) && do {$inJavaSource = 1; last SWITCH;};
($line =~ /^\/\*!\s+\@functiongroup\s*/i) && do {$inFunctionGroup = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@group\s*/i) && do {$inGroup = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@function\s*/i) && do {$inFunction = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@methodgroup\s*/i) && do {$inFunctionGroup = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@method\s*/i) && do {
if ($classType eq "occ" ||
$classType eq "intf" ||
$classType eq "occCat") {
$inMethod = 1;last SWITCH;
} else {
$inFunction = 1;last SWITCH;
}
};
($line =~ /^\/\*!\s+\@typedef\s*/i) && do {$inTypedef = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@union\s*/i) && do {$inUnion = 1;$inStruct = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@struct\s*/i) && do {$inStruct = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@const(ant)?\s*/i) && do {$inConstant = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@var\s*/i) && do {$inVar = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@define(d)?block\s*/i) && do {$inPDefine = 2;last SWITCH;};
($line =~ /^\/\*!\s+\@\/define(d)?block\s*/i) && do {$inPDefine = 0;last SWITCH;};
($line =~ /^\/\*!\s+\@define(d)?\s*/i) && do {$inPDefine = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@lineref\s+(\d+)/) && do {$blockOffset = $1 - $inputCounter; $inputCounter--; print "BLOCKOFFSET SET TO $blockOffset\n" if ($linenumdebug); last SWITCH;};
($line =~ /^\/\*!\s+\@enum\s*/i) && do {$inEnum = 1;last SWITCH;};
($line =~ /^\/\*!\s+\@serial(Data|Field|)\s+/i) && do {$inUnknown = 2;last SWITCH;};
($line =~ /^\/\*!\s*\w/i) && do {$inUnknown = 1;last SWITCH;};
my $linenum = $inputCounter - 1;
print "$filename:$linenum:HeaderDoc comment is not of known type. Comment text is:\n";
print " $line\n";
}
my $linenum = $inputCounter - 1;
my $preAtPart = "";
$line =~ s/\n\n/\n<br><br>\n/g; if ($inUnknown == 1) {
if ($line =~ s/^\s*\/\*!\s*(\w.*?)\@/\/\*! \@/si) {
$preAtPart = $1;
} elsif ($line !~ /^\s*\/\*!\s*.*\@/) {
$preAtPart = $line;
$preAtPart =~ s/^\s*\/\*!\s*//si;
$preAtPart =~ s/\s*\*\/\s*$//si;
$line = "/*! */";
}
print "preAtPart: \"$preAtPart\"\n" if ($localDebug);
print "line: \"$line\"\n" if ($localDebug);
}
my @fields = split(/\@/, $line);
my @newfields = ();
my $lastappend = "";
my $in_textblock = 0;
my $in_link = 0;
foreach my $field (@fields) {
print "processing $field\n" if ($localDebug);
if ($in_textblock) {
if ($field =~ /^\/textblock/) {
print "out of textblock\n" if ($localDebug);
if ($in_textblock == 1) {
my $cleanfield = $field;
$cleanfield =~ s/^\/textblock//i;
$lastappend .= $cleanfield;
push(@newfields, $lastappend);
print "pushed \"$lastappend\"\n" if ($localDebug);
$lastappend = "";
}
$in_textblock = 0;
} else {
$field =~ s/\</\<\;/g;
$field =~ s/\>/\>\;/g;
$lastappend .= "\@$field";
print "new field is \"$lastappend\"\n" if ($localDebug);
}
} else {
if ($field =~ s/^value/<hd_value\/>/si) {
$lastappend = pop(@newfields);
}
if ($field =~ s/^inheritDoc/<hd_ihd\/>/si) {
$lastappend = pop(@newfields);
}
if ($field =~ s/^\/link/<\/hd_link>/i) {
$in_link = 0;
}
if ($field =~ s/^link\s+//i) {
$in_link = 1;
my $target = "";
my $lastfield;
if ($lastappend eq "") {
$lastfield = pop(@newfields);
} else {
$lastfield = "";
}
$lastappend .= $lastfield;
if ($field =~ /^(\S*?)\s/) {
$target = $1;
} else {
$target = $field;
}
my $localDebug = 0;
print "target $target\n" if ($localDebug);
my $qtarget = quote($target);
$field =~ s/^$qtarget//g;
$field =~ s/\\$/\@/;
print "name $field\n" if ($localDebug);
$lastappend .= "<hd_link $target>";
$lastappend .= "$field";
} elsif ($field =~ /^textblock\s/i) {
if ($lastappend eq "") {
$in_textblock = 1;
print "in textblock\n" if ($localDebug);
$lastappend = pop(@newfields);
} else {
$in_textblock = 2;
print "in textblock (continuation)\n" if ($localDebug);
}
$field =~ s/^textblock\s+//i;
$field =~ s/\</\<\;/g;
$field =~ s/\>/\>\;/g;
$lastappend .= "$field";
print "in textblock.\n" if ($localDebug);
} elsif ($field =~ s/\\$/\@/) {
$lastappend .= $field;
} elsif ($lastappend eq "") {
push(@newfields, $field);
} else {
$lastappend .= $field;
push(@newfields, $lastappend);
$lastappend = "";
}
}
}
if (!($lastappend eq "")) {
push(@newfields, $lastappend);
}
if ($in_link) {
warn "$filename:$linenum:Unterminated \@link tag\n";
}
if ($in_textblock) {
warn "$filename:$linenum:Unterminated \@textblock tag\n";
}
@fields = @newfields;
if ($inCPPHeader) {print "inCPPHeader\n" if ($debugging); $HeaderDoc::sublang="cpp"; &processCPPHeaderComment();};
if ($inOCCHeader) {print "inCPPHeader\n" if ($debugging); $HeaderDoc::sublang="occ"; &processCPPHeaderComment();};
if ($inPerlScript) {print "inPerlScript\n" if ($debugging); &processCPPHeaderComment(); $lang="php";};
if ($inPHPScript) {print "inPHPScript\n" if ($debugging); &processCPPHeaderComment(); $lang="php";};
if ($inJavaSource) {print "inJavaSource\n" if ($debugging); &processCPPHeaderComment(); $lang="java";};
if ($inClass) {
$functionGroup = "";
$HeaderDoc::globalGroup = "";
my $classdec = "";
my $pos=$inputCounter;
do {
$classdec .= $inputLines[$pos];
} while (($pos <= $ $classType = &determineClassType($inputCounter, $apiOwner, \@inputLines);
print "CLASS TYPE CHANGED TO $classType\n" if ($ctdebug);
if ($classType eq "C") {
$cppAccessControlState = "";
}
print "inClass 1 - $classType \n" if ($debugging);
$apiOwner = &processClassComment($apiOwner, $rootOutputDir, \@fields, $classType, $inputCounter + $blockOffset);
if ($inInterface) {
$inInterface = 0;
$apiOwner->isCOMInterface(1);
$apiOwner->tocTitlePrefix('COM Interface:');
}
my $superclass = &get_super($classType, $classdec);
if (length($superclass) && (!($apiOwner->checkShortLongAttributes("Superclass")))) {
$apiOwner->attribute("Superclass", $superclass, 0);
}
print "inClass 2\n" if ($debugging);
};
if ($inHeader) {
print "inHeader\n" if ($debugging);
$functionGroup = "";
$HeaderDoc::globalGroup = "";
$apiOwner = &processHeaderComment($apiOwner, $rootOutputDir, \@fields);
$headerDoc::currentClass = $apiOwner;
if ($reprocess_input == 1) {
my @cookedInputLines;
my $localDebug = 0;
foreach my $line (@rawInputLines) {
foreach my $prefix (@perHeaderIgnorePrefixes) {
if ($line =~ s/^\s*$prefix\s*//g) {
print "ignored $prefix\n" if ($localDebug);
}
}
push(@cookedInputLines, $line);
}
@rawInputLines = @cookedInputLines;
$reprocess_input = 2;
goto REDO;
}
};
if ($inGroup) {
print "inGroup\n" if ($debugging);
my $name = $line;
$name =~ s/.*\/\*!\s+\@group\s*//i;
$name =~ s/\s*\*\/.*//;
$name =~ s/\n//smg;
$name =~ s/^\s+//smg;
$name =~ s/\s+$//smg;
print "group name is $name\n" if ($debugging);
$HeaderDoc::globalGroup = $name;
$inputCounter--;
};
if ($inFunctionGroup) {
print "inFunctionGroup\n" if ($debugging);
my $name = $line;
if (!($name =~ s/.*\/\*!\s+\@functiongroup\s*//i)) {
$name =~ s/.*\/\*!\s+\@methodgroup\s*//i;
print "inMethodGroup\n" if ($debugging);
}
$name =~ s/\s*\*\/.*//;
$name =~ s/\n//smg;
$name =~ s/^\s+//smg;
$name =~ s/\s+$//smg;
print "group name is $name\n" if ($debugging);
$functionGroup = $name;
$inputCounter--;
};
if ($inMethod && !$methods_with_new_parser) {
my $methodDebug = 0;
print "inMethod $line\n" if ($methodDebug);
$methObj = HeaderDoc::Method->new;
$methObj->linenum($inputCounter+$blockOffset);
$methObj->apiOwner($apiOwner);
if ($xml_output) {
$methObj->outputformat("hdxml");
} else {
$methObj->outputformat("html");
}
if (length($functionGroup)) {
$methObj->group($functionGroup);
} else {
$methObj->group($HeaderDoc::globalGroup);
}
$methObj->processMethodComment(\@fields);
$methObj->filename($filename);
while (($inputLines[$inputCounter] !~ /\w/) && ($inputCounter <= $ $inputCounter++;
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "method", "9");
print "Input line number: $inputCounter\n" if ($localDebug);
};
my $declaration = $inputLines[$inputCounter];
if ($declaration !~ /;[^;]*$/) { do {
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "method", "10");
$inputCounter++;
print "Input line number: $inputCounter\n" if ($localDebug);
$declaration .= $inputLines[$inputCounter];
} while (($declaration !~ /;[^;]*$/) && ($inputCounter <= $ }
$declaration =~ s/^\s+//g; # trim leading spaces.
$declaration =~ s/([^;]*;).*$/$1/s; $declaration =~ s/\s+;/;/;
print " --> setting method declaration: $declaration\n" if ($methodDebug);
$methObj->setMethodDeclaration($declaration, $classType);
if (length($methObj->name())) {
if (ref($apiOwner) ne "HeaderDoc::Header") {
if ($classType eq "occ" ||
$classType eq "intf" ||
$classType eq "occCat") {
$methObj->accessControl($objcAccessControlState);
} else {
$methObj->accessControl($cppAccessControlState);
}
}
$apiOwner->addToMethods($methObj);
$methObj->apiOwner($apiOwner); print "added method $declaration\n" if ($localDebug);
}
}
if ($inUnknown || $inTypedef || $inStruct || $inEnum || $inUnion || $inConstant || $inVar || $inFunction || ($inMethod && $methods_with_new_parser) || $inPDefine) {
my ($sotemplate, $eotemplate, $operator, $soc, $eoc, $ilc, $sofunction,
$soprocedure, $sopreproc, $lbrace, $rbrace, $unionname, $structname,
$typedefname, $varname, $constname, $structisbrace, $macronameref)
= parseTokens($lang, $HeaderDoc::sublang);
my $varIsConstant = 0;
my $blockmode = 0;
my $curtype = "";
my $blockDebug = 0;
my $parmDebug = 0;
if ($inPDefine == 2) { $blockmode = 1; }
if ($inFunction || $inMethod) {
print "INFUNCTION\n" if ($blockDebug);
my $method = 0;
if ($classType eq "occ" ||
$classType eq "intf" ||
$classType eq "occCat") {
$method = 1;
}
if ($method) {
$curObj = HeaderDoc::Method->new;
$curtype = "method";
} else {
$curObj = HeaderDoc::Function->new;
$curtype = "function";
}
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
if (length($functionGroup)) {
$curObj->group($functionGroup);
} else {
$curObj->group($HeaderDoc::globalGroup);
}
if ($method) {
$curObj->processMethodComment(\@fields);
} else {
$curObj->processFunctionComment(\@fields);
}
$curObj->filename($filename);
} elsif ($inPDefine) {
$curtype = "#define";
$curObj = HeaderDoc::PDefine->new;
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processPDefineComment(\@fields);
$curObj->filename($filename);
} elsif ($inVar) {
$curtype = "constant";
$varIsConstant = 0;
$curObj = HeaderDoc::Var->new;
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processVarComment(\@fields);
$curObj->filename($filename);
} elsif ($inConstant) {
$curtype = "constant";
$varIsConstant = 1;
$curObj = HeaderDoc::Constant->new;
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processConstantComment(\@fields);
$curObj->filename($filename);
} elsif ($inUnknown) {
$curtype = "UNKNOWN";
$curObj = HeaderDoc::HeaderElement->new;
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "typedef", "11");
} elsif ($inTypedef) {
$curtype = $typedefname;
$curObj = HeaderDoc::Typedef->new;
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processTypedefComment(\@fields);
$curObj->masterEnum(0);
$curObj->filename($filename);
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "typedef", "11a");
} elsif ($inStruct || $inUnion) {
if ($inUnion) {
$curtype = "union";
} else {
$curtype = "struct";
}
$curObj = HeaderDoc::Struct->new;
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($inUnion) {
$curObj->isUnion(1);
} else {
$curObj->isUnion(0);
}
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processStructComment(\@fields);
$curObj->filename($filename);
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "typedef", "11b");
} elsif ($inEnum) {
$curtype = "enum";
$curObj = HeaderDoc::Enum->new;
$curObj->masterEnum(1);
$curObj->group($HeaderDoc::globalGroup);
$curObj->apiOwner($apiOwner);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->processEnumComment(\@fields);
$curObj->filename($filename);
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "typedef", "11c");
}
if ($curObj) {
$curObj->linenum($inputCounter+$blockOffset);
}
while (($inputLines[$inputCounter] !~ /\w/) && ($inputCounter <= $ $inputCounter++;
warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "typedef", "12");
print "Input line number: $inputCounter\n" if ($localDebug);
};
print "NEXT LINE is ".$inputLines[$inputCounter].".\n" if ($localDebug);
my $outertype = ""; my $newcount = 0; my $declaration = ""; my $namelist = "";
my $typelist = ""; my $innertype = ""; my $posstypes = "";
print "PTCT: $posstypes =? $curtype\n" if ($localDebug || $blockDebug);
my $blockDec = "";
my $hangDebug = 0;
while (($blockmode || ($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/)) && ($inputCounter <= $
if ($hangDebug) { print "In Block Loop\n"; }
print "DOING SOMETHING\n" if ($localDebug);
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $curObj->documentationBlock();
$HeaderDoc::ignore_apiuid_errors = 0;
my $value = "";
my $pplref = undef;
my $returntype = undef;
my $pridec = "";
my $parseTree = undef;
print "Entering blockParse\n" if ($hangDebug);
($newcount, $declaration, $typelist, $namelist, $posstypes, $value, $pplref, $returntype, $pridec, $parseTree) = &blockParse($filename, $blockOffset, \@inputLines, $inputCounter, 0, \@ignorePrefixes, \@perHeaderIgnorePrefixes);
print "Left blockParse\n" if ($hangDebug);
if ($outertype eq $curtype || $innertype eq $curtype || $posstypes =~ /$curtype/) {
$curObj->declaration($declaration);
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $curObj->documentationBlock();
$HeaderDoc::ignore_apiuid_errors = 0;
}
$curObj->privateDeclaration($pridec);
$parseTree->apiowner($curObj);
$curObj->parseTree($parseTree);
my @parsedParamList = @{$pplref};
print "VALUE IS $value\n" if ($localDebug);
my $method = 0;
if ($classType eq "occ" ||
$classType eq "intf" ||
$classType eq "occCat") {
$method = 1;
}
$declaration =~ s/^\s*//s;
print "obtained declaration\n" if ($localDebug);
$inputCounter = $newcount;
my @oldnames = split(/[,;]/, $namelist);
my @oldtypes = split(/ /, $typelist);
$outertype = $oldtypes[0];
if ($outertype eq "") {
$outertype = $curtype;
my $linenum = $inputCounter + $blockOffset;
warn("$filename:$linenum:Parser bug: empty outer type\n");
warn("IC: $inputCounter\n");
warn("DC: \"$declaration\"\n");
warn("TL: \"$typelist\"\n");
warn("DC: \"$namelist\"\n");
warn("DC: \"$posstypes\"\n");
}
$innertype = $oldtypes[scalar(@oldtypes)-1];
if ($localDebug) {
foreach my $ot (@oldtypes) {
print "TYPE: \"$ot\"\n";
}
}
my $explicit_name = 1;
my $curname = $curObj->name();
$curname =~ s/^\s*//;
$curname =~ s/\s*$//;
my @names = ( ); my @types = ( ); if (length($curname) && length($curtype)) {
push(@names, $curname);
push(@types, $outertype);
}
my $count = 0;
my $operator = 0;
if ($typelist eq "operator") {
$operator = 1;
}
foreach my $name (@oldnames) {
if ($operator) {
$name =~ s/^\s*operator\s*//s;
$name = "operator $name";
$curname =~ s/^operator(\W)/operator $1/s;
}
if (($name eq $curname) && ($oldtypes[$count] eq $outertype)) {
$explicit_name = 0;
$count++;
} else {
push(@names, $name);
push(@types, $oldtypes[$count++]);
}
}
if ($hangDebug) { print "Point A\n"; }
my $count = 0;
foreach my $name (@names) {
my $localDebug = 0;
my $typestring = $types[$count++];
print "NAME IS $name\n" if ($localDebug);
print "CURNAME IS $curname\n" if ($localDebug);
print "TYPESTRING IS $typestring\n" if ($localDebug);
print "CURTYPE IS $curtype\n" if ($localDebug);
print "MATCH: $name IS A $typestring.\n" if ($localDebug);
print "DEC ($name / $typestring): $declaration\n" if ($localDebug);
$name =~ s/\s*$//g;
$name =~ s/^\s*//g;
my $cmpname = $name;
my $cmpcurname = $curname;
$cmpname =~ s/:$//s;
$cmpcurname =~ s/:$//s;
if (!length($name)) { next; }
print "Got $name ($curname)\n" if ($localDebug);
my $extra = undef;
if ($typestring eq $curtype && ($cmpname eq $cmpcurname || !length($curname))) {
print "$curtype = $typestring\n" if ($localDebug);
$extra = $curObj;
if ($blockmode) {
$blockDec .= $declaration;
print "SPDF[1]\n" if ($hangDebug);
$curObj->isBlock(1);
$curObj->setPDefineDeclaration($blockDec);
print "END SPDF[1]\n" if ($hangDebug);
}
} else {
print "NAME IS $name\n" if ($localDebug);
if ($curtype eq "function" && $posstypes =~ /function/) {
$curtype = "UNKNOWN";
}
if ($typestring eq $outertype || !$HeaderDoc::outerNamesOnly) {
if ($typestring =~ /^$typedefname/ && length($typedefname)) {
print "blockParse returned $typedefname\n" if ($localDebug);
$extra = HeaderDoc::Typedef->new;
$extra->group($HeaderDoc::globalGroup);
$curObj->masterEnum(1);
if ($curtype eq "UNKNOWN") {
$extra->processTypedefComment(\@fields);
}
} elsif ($typestring =~ /^struct/ || $typestring =~ /^union/ || ($lang eq "pascal" && $typestring =~ /^record/)) {
print "blockParse returned struct or union ($typestring)\n" if ($localDebug);
$extra = HeaderDoc::Struct->new;
$extra->group($HeaderDoc::globalGroup);
if ($typestring =~ /union/) {
$extra->isUnion(1);
}
if ($curtype eq "UNKNOWN") {
$extra->processStructComment(\@fields);
}
} elsif ($typestring =~ /^enum/) {
print "blockParse returned enum\n" if ($localDebug);
$extra = HeaderDoc::Enum->new;
$extra->group($HeaderDoc::globalGroup);
if ($curtype eq "UNKNOWN") {
$extra->processEnumComment(\@fields);
}
if ($curtype eq "enum" || $curtype eq "typedef") {
$extra->masterEnum(0);
} else {
$extra->masterEnum(1);
}
} elsif ($typestring =~ /^MACRO/) {
print "blockParse returned MACRO\n" if ($localDebug);
} elsif ($typestring =~ /^\ print "blockParse returned #define\n" if ($localDebug);
$extra = HeaderDoc::PDefine->new;
$extra->group($HeaderDoc::globalGroup);
if ($curtype eq "UNKNOWN") {
$extra->processPDefineComment(\@fields);
}
} elsif ($typestring =~ /^constant/) {
if ($declaration =~ /\s+const\s+/) {
$varIsConstant = 1;
print "blockParse returned constant\n" if ($localDebug);
$extra = HeaderDoc::Constant->new;
$extra->group($HeaderDoc::globalGroup);
if ($curtype eq "UNKNOWN") {
$extra->processConstantComment(\@fields);
}
} else {
$varIsConstant = 0;
print "blockParse returned variable\n" if ($localDebug);
$extra = HeaderDoc::Var->new;
$extra->group($HeaderDoc::globalGroup);
if ($curtype eq "UNKNOWN") {
$extra->processVarComment(\@fields);
}
}
} elsif ($typestring =~ /^(function|method|operator|ftmplt)/) {
print "blockParse returned function or method\n" if ($localDebug);
if ($method) {
$extra = HeaderDoc::Method->new;
if ($curtype eq "UNKNOWN") {
$extra->processMethodComment(\@fields);
}
if (length($functionGroup)) {
$extra->group($functionGroup);
} else {
$extra->group($HeaderDoc::globalGroup);
}
} else {
$extra = HeaderDoc::Function->new;
if (length($functionGroup)) {
$extra->group($functionGroup);
} else {
$extra->group($HeaderDoc::globalGroup);
}
if ($curtype eq "UNKNOWN") {
$extra->processFunctionComment(\@fields);
}
}
if ($typestring eq "ftmplt") {
$extra->isTemplate(1);
}
} else {
my $linenum = $inputCounter + $blockOffset;
warn("$filename:$linenum:Unknown keyword $typestring in block-parsed declaration\n");
}
if ($extra) {
$extra->linenum($inputCounter+$blockOffset);
}
}
}
if ($hangDebug) { print "Point B\n"; }
if ($curtype eq "UNKNOWN") {
$curObj = $extra;
}
if ($extra) {
my $extraclass = ref($extra) || $extra;
my $abstract = $curObj->abstract();
my $discussion = $curObj->discussion();
my $pridec = $curObj->privateDeclaration();
$extra->privateDeclaration($pridec);
my $orig_parsetree = $curObj->parseTree($parseTree);
bless($orig_parsetree, "HeaderDoc::ParseTree");
$extra->parseTree($orig_parsetree->clone());
if ($blockmode) {
my $discussionParam = $curObj->taggedParamMatching($name);
if ($discussionParam) {
$discussion = $discussionParam->discussion;
}
if ($curObj != $extra) {
$curObj->addParsedParameter($extra);
}
}
print "Point B1\n" if ($hangDebug);
if ($extraclass !~ /HeaderDoc::Method/) {
print "Point B2\n" if ($hangDebug);
my $paramName = "";
my $position = 0;
my $type = "";
$extra->returntype($returntype);
my @tempPPL = @parsedParamList;
foreach my $parsedParam (@tempPPL) {
if (0) {
print "PARSED PARAM: \"$parsedParam\"\n" if ($parmDebug);
if ($parsedParam =~ s/(\w+\)*)$//s) {
$paramName = $1;
} else {
$paramName = "";
}
$parsedParam =~ s/\s*$//s;
if (!length($parsedParam)) {
$type = $paramName;
$paramName = "";
} else {
$type = $parsedParam;
}
print "NAME: $paramName\nType: $type\n" if ($parmDebug);
my $param = HeaderDoc::MinorAPIElement->new();
$param->linenum($inputCounter+$blockOffset);
$param->outputformat($extra->outputformat);
$param->name($paramName);
$param->position($position++);
$param->type($type);
$extra->addParsedParameter($param);
} else {
my $ppDebug = 0 || $parmDebug;
print "PARSED PARAM: \"$parsedParam\"\n" if ($ppDebug);
my $ppstring = $parsedParam;
$ppstring =~ s/^\s*//sg;
$ppstring =~ s/\s*$//sg;
my $foo;
my $dec;
my $pridec;
my $type;
my $name;
my $pt;
my $value;
my $pplref;
my $returntype;
if ($ppstring eq "...") {
$name = $ppstring;
$type = "";
$pt = "";
} else {
$ppstring .= ";";
my @array = ( $ppstring );
my $parseTree = undef;
($foo, $dec, $type, $name, $pt, $value, $pplref, $returntype, $pridec, $parseTree) = &blockParse($filename, $extra->linenum(), \@array, 0, 1, \@ignorePrefixes, \@perHeaderIgnorePrefixes);
}
if ($ppDebug) {
print "NAME: $name\n";
print "TYPE: $type\n";
print "PT: $pt\n";
}
my $param = HeaderDoc::MinorAPIElement->new();
$param->linenum($inputCounter+$blockOffset);
$param->outputformat($extra->outputformat);
$param->name($name);
$param->position($position++);
$param->type($returntype);
$extra->addParsedParameter($param);
}
}
} else {
my @newpps = $parseTree->objCparsedParams();
foreach my $newpp (@newpps) {
$extra->addParsedParameter($newpp);
}
}
print "Point B3\n" if ($hangDebug);
if (length($preAtPart)) {
print "preAtPart: $preAtPart\n" if ($localDebug);
$extra->discussion($preAtPart);
} elsif ($extra != $curObj) {
$extra->discussion($discussion);
}
print "Point B4\n" if ($hangDebug);
$extra->abstract($abstract);
if (length($value)) { $extra->value($value); }
if ($extra != $curObj || !length($curObj->name())) {
$name =~ s/^(\s|\*)*//sg;
}
print "NAME IS $name\n" if ($localDebug);
$extra->rawname($name);
print "Point B5\n" if ($hangDebug);
$HeaderDoc::ignore_apiuid_errors = 1;
$extra->name($name);
my $junk = $extra->documentationBlock();
$HeaderDoc::ignore_apiuid_errors = 0;
if ($extra != $curObj) {
my @constants = $curObj->constants();
foreach my $constant (@constants) {
if ($extra->can("addToConstants")) {
$extra->addToConstants($constant->clone());
} elsif ($extra->can("addConstant")) {
$extra->addConstant($constant->clone());
}
}
print "Point B6\n" if ($hangDebug);
if (length($curObj->name())) {
my $ern = $extra->rawname();
if ($ern =~ /\s/ && $localDebug) {
print "changed space to ctrl-d\n";
print "ref is ".$extra->apiuid()."\n";
}
$ern =~ s/\s/\cD/sg;
my $crn = $curObj->rawname();
if ($crn =~ /\s/ && $localDebug) {
print "changed space to ctrl-d\n";
print "ref is ".$curObj->apiuid()."\n";
}
$crn =~ s/\s/\cD/sg;
$curObj->attributelist("See Also", $ern." ".$extra->apiuid());
$extra->attributelist("See Also", $crn." ".$curObj->apiuid());
}
}
print "Point B7 TS = $typestring\n" if ($hangDebug);
if (ref($apiOwner) ne "HeaderDoc::Header") {
$extra->accessControl($cppAccessControlState); }
if ($curObj->can("fields") && $extra->can("fields")) {
my @fields = $curObj->fields();
foreach my $field (@fields) {
bless($field, "HeaderDoc::MinorAPIElement");
$extra->addField($field->clone());
}
}
$extra->apiOwner($apiOwner);
if ($xml_output) {
$extra->outputformat("hdxml");
} else {
$extra->outputformat("html");
}
$extra->filename($filename);
if ($typestring =~ /$typedefname/ && length($typedefname)) {
if (length($declaration)) {
$extra->setTypedefDeclaration($declaration);
}
if (length($extra->name())) {
if (ref($apiOwner) ne "HeaderDoc::Header") {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra); }
} else { if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToTypedefs($extra); }
}
}
} elsif ($typestring =~ /MACRO/) {
} elsif ($typestring =~ / print "SPDF[2]\n" if ($hangDebug);
$extra->setPDefineDeclaration($declaration);
print "END SPDF[2]\n" if ($hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToPDefines($extra); }
} elsif ($typestring =~ /struct/ || $typestring =~ /union/ || ($lang eq "pascal" && $typestring =~ /record/)) {
if ($typestring =~ /union/) {
$extra->isUnion(1);
} else {
$extra->isUnion(0);
}
$extra->setStructDeclaration($declaration);
if (ref($apiOwner) ne "HeaderDoc::Header") {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra); }
} else {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToStructs($extra); }
}
} elsif ($typestring =~ /enum/) {
$extra->declaration($declaration);
$extra->declarationInHTML($extra->getEnumDeclaration($declaration));
if (ref($apiOwner) ne "HeaderDoc::Header") {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra); }
} else {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToEnums($extra); }
}
} elsif ($typestring =~ /\ print "SPDF[3]\n" if ($hangDebug);
$extra->setPDefineDeclaration($declaration);
print "END SPDF[3]\n" if ($hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) { $headerObject->addToPDefines($extra); }
} elsif ($typestring =~ /(function|method|operator|ftmplt)/) {
if ($method) {
$extra->setMethodDeclaration($declaration);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToMethods($extra); }
} else {
print "SFD\n" if ($hangDebug);
$extra->setFunctionDeclaration($declaration);
print "END SFD\n" if ($hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToFunctions($extra); }
}
if ($typestring eq "ftmplt") {
$extra->isTemplate(1);
}
} elsif ($typestring =~ /constant/) {
$extra->declaration($declaration);
if ($varIsConstant) {
$extra->setConstantDeclaration($declaration);
if (length($extra->name())) {
if (ref($apiOwner) ne "HeaderDoc::Header") {
$extra->accessControl($cppAccessControlState);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra); }
} else { if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToConstants($extra); }
}
}
} else {
$extra->setVarDeclaration($declaration);
if (ref($apiOwner) ne "HeaderDoc::Header") {
$extra->accessControl($cppAccessControlState);
}
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra); }
}
} else {
my $linenum = $inputCounter + $blockOffset;
warn("$filename:$linenum:Unknown typestring $typestring returned by blockParse\n");
}
$extra->checkDeclaration();
}
}
if ($hangDebug) {
print "Point C\n";
print "inputCounter is $inputCounter, #inputLines is $#inputLines\n";
}
while ($inputLines[$inputCounter] !~ /\S/ && ($inputCounter <= $ if ($hangDebug) { print "Point D\n"; }
if ($curtype eq "UNKNOWN") { $curtype = $outertype; }
if ((($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/)) && (($inputCounter > $ warn "No matching declaration found. Last name was $curname\n";
warn "$outertype ne $curtype && $innertype ne $curtype && $posstypes !~ $curtype\n";
last;
}
if ($hangDebug) { print "Point E\n"; }
if ($blockmode) {
warn "next line: ".$inputLines[$inputCounter]."\n" if ($hangDebug);
$blockmode = 2;
$HeaderDoc::ignore_apiuid_errors = 1;
if (warnHDComment($inputLines[$inputCounter], $inputCounter + $blockOffset, "blockParse:$outertype", "18a")) {
$blockmode = 0;
warn "Block Mode Ending\n" if ($hangDebug);
}
$HeaderDoc::ignore_apiuid_errors = 0;
}
print "PTCT: $posstypes =? $curtype\n" if ($localDebug || $blockDebug);
}
if (length($blockDec)) {
$curObj->declaration($blockDec);
$curObj->declarationInHTML($blockDec);
}
if ($hangDebug) { print "Point F\n"; }
print "Out of Block\n" if ($localDebug || $blockDebug);
$inputCounter--;
}
}
$inCPPHeader = $inOCCHeader = $inPerlScript = $inShellScript = $inPHPScript = $inJavaSource = $inHeader = $inUnknown = $inFunction = $inFunctionGroup = $inGroup = $inTypedef = $inUnion = $inStruct = $inConstant = $inVar = $inPDefine = $inEnum = $inMethod = $inClass = 0;
$inputCounter++;
print "Input line number: $inputCounter\n" if ($localDebug);
}
if (ref($apiOwner) ne "HeaderDoc::Header") { my $name = $apiOwner->name();
my $refName = ref($apiOwner);
SWITCH: {
($classType eq "php" ) && do {
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
last SWITCH; };
($classType eq "java" ) && do {
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
last SWITCH; };
($classType eq "cpp" ) && do {
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
last SWITCH; };
($classType eq "cppt" ) && do {
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
last SWITCH; };
($classType eq "occ") && do {
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
$objCClassNameToObject{$apiOwner->name()} = $apiOwner;
last SWITCH; };
($classType eq "intf") && do {
push (@classObjects, $apiOwner);
$headerObject->addToProtocols($apiOwner);
last SWITCH;
};
($classType eq "occCat") && do {
push (@categoryObjects, $apiOwner);
print "INSERTED CATEGORY into $headerObject\n" if ($ctdebug);
$headerObject->addToCategories($apiOwner);
last SWITCH;
};
($classType eq "C") && do {
$cppAccessControlState = "";
push (@classObjects, $apiOwner);
$headerObject->addToClasses($apiOwner);
last SWITCH;
};
foreach my $testclass ( $headerObject->classes() ) { print $testclass->name() . "\n"; }
my $linenum = $inputCounter - 1;
print "$filename:$linenum:Unknown class type '$classType' (known: cpp, objC, intf, occCat)\n";
}
}
} push (@headerObjects, $headerObject);
}
if (!$quietLevel) {
print "======= Beginning post-processing =======\n";
}
if (@classObjects && !$xml_output) {
foreach my $class (@classObjects) {
mergeClass($class);
}
}
if (@categoryObjects && !$xml_output) {
foreach my $obj (@categoryObjects) {
my $nameOfAssociatedClass = $obj->className();
my $categoryName = $obj->categoryName();
my $localDebug = 0;
if (exists $objCClassNameToObject{$nameOfAssociatedClass}) {
my $associatedClass = $objCClassNameToObject{$nameOfAssociatedClass};
$associatedClass->addToMethods($obj->methods());
my $owner = $obj->headerObject();
print "Found category with name $categoryName and associated class $nameOfAssociatedClass\n" if ($localDebug);
print "Associated class exists\n" if ($localDebug);
print "Added methods to associated class\n" if ($localDebug);
if (ref($owner)) {
my $numCatsBefore = $owner->categories();
$owner->removeFromCategories($obj);
my $numCatsAfter = $owner->categories();
print "Number of categories before: $numCatsBefore after:$numCatsAfter\n" if ($localDebug);
} else {
my $filename = $HeaderDoc::headerObject->filename();
my $linenum = $obj->linenum();
print "$filename:$linenum:Couldn't find Header object that owns the category with name $categoryName.\n";
}
} else {
print "Found category with name $categoryName and associated class $nameOfAssociatedClass\n" if ($localDebug);
print "Associated class doesn't exist\n" if ($localDebug);
}
}
}
foreach my $obj (@headerObjects) {
if ($xml_output) {
$obj->writeHeaderElementsToXMLPage();
} else {
$obj->createFramesetFile();
$obj->createTOCFile();
$obj->writeHeaderElements();
$obj->writeHeaderElementsToCompositePage();
$obj->createContentFile();
$obj->writeExportsWithName($rootFileName) if (($export) || ($testingExport));
}
if ("$write_control_file" eq "1") {
print "Writing doc server control file... ";
$obj->createMetaFile();
print "done.\n";
}
}
if ($quietLevel eq "0") {
print "...done\n";
}
exit 0;
sub warnHDComment
{
my $line = shift;
my $linenum = shift;
my $dectype = shift;
my $dp = shift;
my $filename = $HeaderDoc::headerObject->filename();
my $localDebug = 2;
my $debugString = "";
if ($localDebug) { $debugString = " [debug point $dp]"; }
if ($line =~ /\/\*\!/) {
if (!$HeaderDoc::ignore_apiuid_errors) {
warn("$filename:$linenum: WARNING: Unexpected headerdoc markup found in $dectype declaration$debugString. Output may be broken.\n");
}
return 1;
}
return 0;
}
sub mergeClass
{
my $class = shift;
my $superName = $class->checkShortLongAttributes("Superclass");
my $merge_content = 1;
if ($class->isMerged()) { return; }
if (!$class->explicitSuper() && !$HeaderDoc::IncludeSuper) {
$merge_content = 0;
}
if ($superName) {
if (!($superName eq $class->name())) {
my $super = 0;
foreach my $mergeclass (@classObjects) {
if ($mergeclass->name eq $superName) {
$super = $mergeclass;
}
}
if ($super) {
if (!$super->isMerged()) {
mergeClass($super);
}
my @methods = $super->methods();
my @functions = $super->functions();
my @vars = $super->vars();
my @structs = $super->structs();
my @enums = $super->enums();
my @pdefines = $super->pDefines();
my @typedefs = $super->typedefs();
my @constants = $super->constants();
my @classes = $super->classes();
my $name = $super->name();
my $discussion = $super->discussion();
$class->inheritDoc($discussion);
if ($merge_content) {
my @childfunctions = $class->functions();
my @childmethods = $class->methods();
my @childvars = $class->vars();
my @childstructs = $class->structs();
my @childenums = $class->enums();
my @childpdefines = $class->pDefines();
my @childtypedefs = $class->typedefs();
my @childconstants = $class->constants();
my @childclasses = $class->classes();
if (@methods) {
foreach my $method (@methods) {
if ($method->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childmethod (@childmethods) {
if ($method->name() eq $childmethod->name()) {
if ($method->parsedParamCompare($childmethod)) {
$include = 0; last;
}
}
}
if (!$include) { next; }
my $newobj = $method->clone();
$class->addToMethods($method);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@functions) {
foreach my $function (@functions) {
if ($function->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childfunction (@childfunctions) {
if ($function->name() eq $childfunction->name()) {
if ($function->parsedParamCompare($childfunction)) {
$include = 0; last;
}
}
}
if (!$include) { next; }
my $newobj = $function->clone();
$class->addToFunctions($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@vars) {
foreach my $var (@vars) {
if ($var->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childvar (@childvars) {
if ($var->name() eq $childvar->name()) {
$include = 0; last;
}
}
if (!$include) { next; }
my $newobj = $var->clone();
$class->addToVars($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@structs) {
foreach my $struct (@structs) {
if ($struct->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childstruct (@childstructs) {
if ($struct->name() eq $childstruct->name()) {
$include = 0; last;
}
}
my $newobj = $struct->clone();
$class->addToStructs($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@enums) {
foreach my $enum (@enums) {
if ($enum->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childenum (@childenums) {
if ($enum->name() eq $childenum->name()) {
$include = 0; last;
}
}
my $newobj = $enum->clone();
$class->addToEnums($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@pdefines) {
foreach my $pdefine (@pdefines) {
if ($pdefine->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childpdefine (@childpdefines) {
if ($pdefine->name() eq $childpdefine->name()) {
$include = 0; last;
}
}
my $newobj = $pdefine->clone();
$class->addToPDefines($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@typedefs) {
foreach my $typedef (@typedefs) {
if ($typedef->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childtypedef (@childtypedefs) {
if ($typedef->name() eq $childtypedef->name()) {
$include = 0; last;
}
}
my $newobj = $typedef->clone();
$class->addToTypedefs($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@constants) {
foreach my $constant (@constants) {
if ($constant->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childconstant (@childconstants) {
if ($constant->name() eq $childconstant->name()) {
$include = 0; last;
}
}
my $newobj = $constant->clone();
$class->addToConstants($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
if (@classes) {
foreach my $class (@classes) {
if ($class->accessControl() eq "private") {
next;
}
my $include = 1;
foreach my $childclass (@childclasses) {
if ($class->name() eq $childclass->name()) {
$include = 0; last;
}
}
my $newobj = $class->clone();
$class->addToClasses($newobj);
$newobj->apiOwner($class);
if ($newobj->origClass() eq "") {
$newobj->origClass($name);
}
}
}
} }
}
}
$class->isMerged(1);
}
sub emptyHDok
{
my $line = shift;
my $okay = 0;
SWITCH: {
($line =~ /\@(function|method|)group/) && do { $okay = 1; };
($line =~ /\@language/) && do { $okay = 1; };
($line =~ /\@header/) && do { $okay = 1; };
($line =~ /\@framework/) && do { $okay = 1; };
($line =~ /\@\/define(d)?block/) && do { $okay = 1; };
($line =~ /\@lineref/) && do { $okay = 1; };
}
return $okay;
}
sub getLineArrays {
my $classDebug = 0;
my $localDebug = 0;
my $blockDebug = 0;
my $rawLineArrayRef = shift;
my @arrayOfLineArrays = ();
my @generalHeaderLines = ();
my @classStack = ();
my $inputCounter = 0;
my $lastArrayIndex = @{$rawLineArrayRef};
my $line = "";
my $className = "";
my $classType = "";
while ($inputCounter <= $lastArrayIndex) {
$line = ${$rawLineArrayRef}[$inputCounter];
my $startline = $inputCounter;
print "MYLINE: $line\n" if ($localDebug);
if (($line =~ /^\s*\/\*\!/) || (($lang eq "java") && ($line =~ /^\s*\/\*\*/))) { print "inHDComment\n" if ($localDebug);
my $headerDocComment = "";
{
local $^W = 0; my $in_textblock = 0; my $in_pre = 0;
while (($line !~ /\*\//) && ($inputCounter <= $lastArrayIndex)) {
$line =~ s/\{\s*\@linkplain\s+(.*?)\}/\@link $1\@\/link/sgi;
$line =~ s/\{\s*\@link\s+(.*?)\}/<code>\@link $1\@\/link<\/code>/sgi;
$line =~ s/\{\s*\@docroot\s*\}/\\\@\\\@docroot/gi;
$line =~ s/\{\@value\}/\@value/sgi;
$line =~ s/\{\@inheritDoc\}/\@inheritDoc/sgi;
$line =~ s/([^\\])\@docroot/$1\\\@\\\@docroot/gi;
my $templine = $line;
while ($templine =~ s/\@textblock//i) { $in_textblock++; }
while ($templine =~ s/\@\/textblock//i) { $in_textblock--; }
while ($templine =~ s/<pre>//i) { $in_pre++; }
while ($templine =~ s/<\/pre>//i) { $in_pre--; }
if (!$in_textblock && !$in_pre) {
$line =~ s/^[ \t]*//; # remove leading whitespace
}
$line =~ s/^[*]\s*$/\n/; $line =~ s/^[*]\s+(.*)/$1/; $headerDocComment .= $line;
$line = ${$rawLineArrayRef}[++$inputCounter];
warnHDComment(${$rawLineArrayRef}[$inputCounter], $inputCounter, "HeaderDoc comment", "33");
}
$line =~ s/\{\s*\@docroot\s*\}/\\\@\\\@docroot/g;
$headerDocComment .= $line ;
$line = ${$rawLineArrayRef}[++$inputCounter];
if (!emptyHDok($headerDocComment)) {
my $emptyDebug = 0;
warn "curline is $line" if ($emptyDebug);
warnHDComment(${$rawLineArrayRef}[$inputCounter], $inputCounter, "HeaderDoc comment", "35");
}
}
my $name = ""; my $type = "";
if (($headerDocComment =~ /^\/\*!\s*\@class|\@interface|\@protocol|\@category\s*/i ||
($headerDocComment =~ /^\/\*\!\s*\w+/ && (($name,$type)=classLookAhead($rawLineArrayRef, $inputCounter, $lang, $HeaderDoc::sublang)))) ||
($lang eq "java" &&
($headerDocComment =~ /^\/\*!\s*\@class|\@interface|\@protocol|\@category\s*/i ||
($headerDocComment =~ /^\/\*\*\s*\w+/ && (($name,$type)=classLookAhead($rawLineArrayRef, $inputCounter, $lang, $HeaderDoc::sublang)))))) {
print "INCLASS\n" if ($localDebug);
if (length($type)) {
$headerDocComment =~ s/\/\*(\*|\!)/\/\*$1 \@$type $name\n/s;
print "CLARETURNED: \"$name\" \"$type\"\n" if ($localDebug || $classDebug || $blockDebug);
}
my $class = HeaderDoc::ClassArray->new();
my $ln = $startline;
my $linenumline = "/*! \@lineref $ln */\n";
if ($lang eq "perl" || $lang eq "shell") {
$linenumline = "# $linenumline";
}
$class->push($linenumline);
($className = $headerDocComment) =~ s/.*\@class|\@protocol|\@category\s+(\w+)\s+.*/$1/s;
$class->pushlines ($headerDocComment);
while (($line !~ /class\s|\@class|\@interface\s|\@protocol\s|typedef\s+struct\s/) && ($inputCounter <= $lastArrayIndex)) {
$class->push ($line);
warnHDComment(${$rawLineArrayRef}[$inputCounter], $inputCounter, "class", "36");
$line = ${$rawLineArrayRef}[++$inputCounter];
warnHDComment(${$rawLineArrayRef}[$inputCounter], $inputCounter, "class", "37");
}
my $initial_bracecount = 0; print "[CLASSTYPE]line $line\n" if ($localDebug);
SWITCH: {
($line =~ /^\s*\@protocol\s+/ ) &&
do {
$classType = "objCProtocol";
$HeaderDoc::sublang="occ";
$initial_bracecount++;
last SWITCH;
};
($line =~ /^\s*typedef\s+struct\s+/ ) &&
do {
$classType = "C";
last SWITCH;
};
($line =~ /^\s*template\s+/ ) &&
do {
$classType = "cppt";
$HeaderDoc::sublang="cpp";
last SWITCH;
};
($line =~ /^\s*(public|private|protected|)\s*class\s+/ ) &&
do {
$classType = "cpp";
$HeaderDoc::sublang="cpp";
last SWITCH;
};
($line =~ /^\s*(\@class|\@interface)\s+/ ) &&
do {
if ($line =~ /\(.*\)/) {
$classType = "objCCategory";
} else {
$classType = "objC";
}
$HeaderDoc::sublang="occ";
if ($1 ne "\@class") {
$initial_bracecount++;
}
last SWITCH;
};
print "Unknown class type (known: cpp, cppt, objCCategory, objCProtocol, C,)\nline=\"$line\"";
}
if ($lang eq "php") {$classType = "php";}
elsif ($lang eq "java") {$classType = "java";}
my $inClassBraces = $initial_bracecount;
my $leftBraces = 0;
my $rightBraces = 0;
if (!($initial_bracecount) && $line !~ /;/) {
while (($inputCounter <= $lastArrayIndex)
&& (!($leftBraces))) {
print "[IP]line=$line\n" if ($localDebug);
$class->push ($line);
$leftBraces = $line =~ tr/{//;
$rightBraces = $line =~ tr/}//;
$inClassBraces += $leftBraces;
$inClassBraces -= $rightBraces;
warnHDComment(${$rawLineArrayRef}[$inputCounter], $inputCounter, "class", "38");
$line = ${$rawLineArrayRef}[++$inputCounter];
}
}
$class->push($line);
$class->bracecount_inc($inClassBraces);
my $bc = $class->bracecount();
print "NEW: pushing class $class bc=$bc\n" if ($classDebug);
print "CURLINE: $line\n" if ($localDebug);
push(@classStack, $class);
} else {
print "[2] line = $line\n" if ($localDebug);
my $class = pop(@classStack);
if ($class) {
my $bc = $class->bracecount();
print "popped class $class bc=$bc\n" if ($classDebug);
$class->pushlines($headerDocComment);
$class->push($line);
if (($classType =~ /cpp/) || ($classType =~ /^C/) || ($classType =~ /cppt/) ||
($classType =~ /php/) || ($classType =~ /java/)) {
my $leftBraces = $headerDocComment =~ tr/{// + $line =~ tr/{//;
$class->bracecount_inc($leftBraces);
my $rightBraces = $headerDocComment =~ tr/}// + $line =~ tr/}//;
$class->bracecount_dec($rightBraces);
}
if (($classType =~ /objC/) || ($classType =~ /objCProtocol/) || ($classType =~ /objCCategory/)) {
if ($headerDocComment =~ /\@end/ || $line =~ /\@end/) {
$class->bracecount_dec();
}
}
if (my $bc=$class->bracecount()) {
print "pushing class $class bc=$bc\n" if ($classDebug);
push(@classStack, $class);
} else {
my @array = $class->getarray();
push (@arrayOfLineArrays, \@array);
print "OUT OF CLASS[2]! (headerDocComment: $inputCounter $headerDocComment)\n" if ($localDebug);
my $tc = pop(@classStack);
my $ln = $inputCounter + 1;
my $linenumline = "/*! \@lineref $ln */\n";
if ($lang eq "perl" || $lang eq "shell") {
$linenumline = "# $linenumline";
}
if ($tc) {
$tc->push($linenumline);
push(@classStack, $tc);
} else {
push(@generalHeaderLines, $linenumline);
}
if ($localDebug) {
print "array is:\n";
foreach my $arrelem (@array) {
print "$arrelem\n";
}
print "end of array.\n";
}
}
} else {
my @linearray = split (/\n/, $headerDocComment);
foreach my $arrayline (@linearray) {
push(@generalHeaderLines, "$arrayline\n");
}
push(@generalHeaderLines, $line);
}
}
} else {
print "[3]line=$line\n" if ($classDebug > 3);
my $class = pop(@classStack);
if ($class) {
my $bc = $class->bracecount();
print "[tail]popped class $class bc=$bc\n" if ($classDebug);
$class->push($line);
print "pushed line $line\n" if ($classDebug);
if (($classType =~ /cpp/) || ($classType =~ /^C/) || ($classType =~ /cppt/) ||
($classType =~ /php/) || ($classType =~ /java/)) {
my $leftBraces = $line =~ tr/{//;
$class->bracecount_inc($leftBraces);
my $rightBraces = $line =~ tr/}//;
$class->bracecount_dec($rightBraces);
print "lb=$leftBraces, rb=$rightBraces\n" if ($localDebug);
} elsif (($classType =~ /objC/) || ($classType =~ /objCProtocol/) || ($classType =~ /objCCategory/)) {
if ($line =~ /\@end/) {
$class->bracecount_dec();
}
my $leftBraces = $line =~ tr/{//;
$class->bracecount_inc($leftBraces);
my $rightBraces = $line =~ tr/}//;
$class->bracecount_dec($rightBraces);
print "lb=$leftBraces, rb=$rightBraces\n" if ($localDebug || $classDebug);
my $bc = $class->bracecount();
print "bc=$bc\n" if ($localDebug || $classDebug);
} else {
print "WARNING: Unknown classtype $classType\n";
}
if (my $bc=$class->bracecount()) {
print "pushing class $class bc=$bc\n" if ($classDebug);
push(@classStack, $class);
} else {
my @array = $class->getarray();
push (@arrayOfLineArrays, \@array);
print "OUT OF CLASS! (line: $inputCounter $line)\n" if ($localDebug);
my $tc = pop(@classStack);
my $ln = $inputCounter + 1;
my $linenumline = "/*! \@lineref $ln */\n";
if ($lang eq "perl" || $lang eq "shell") {
$linenumline = "# $linenumline";
}
if ($tc) {
$tc->push($linenumline);
push(@classStack, $tc);
} else {
push(@generalHeaderLines, $linenumline);
}
my $localDebug = 0;
if ($localDebug) {
print "array is:\n";
foreach my $arrelem (@array) {
print "$arrelem\n";
}
print "end of array.\n";
}
}
} else {
push (@generalHeaderLines, $line); print "PUSHED $line\n" if ($blockDebug);
}
}
$inputCounter++;
}
push (@arrayOfLineArrays, \@generalHeaderLines);
return @arrayOfLineArrays;
}
sub processCPPHeaderComment {
return;
}
sub removeSlashSlashComment {
my $line = shift;
$line =~ s/\/\/.*$//;
return $line;
}
sub get_super {
my $classType = shift;
my $dec = shift;
my $super = "";
my $localDebug = 0;
print "GS: $dec EGS\n" if ($localDebug);
$dec =~ s/\n/ /smg;
if ($classType =~ /^occ/) {
if ($dec !~ s/^\s*\@interface\s*//s) {
if ($dec !~ s/^\s*\@protocol\s*//s) {
$dec !~ s/^\s*\@class\s*//s;
}
}
if ($dec =~ /(\w+)\s*\(\s*(\w+)\s*\)/) {
$super = $1; } elsif (!($dec =~ s/.*?://s)) {
$super = "";
} else {
$dec =~ s/\(.*//sg;
$dec =~ s/\{.*//sg;
$super = $dec;
}
} elsif ($classType =~ /^cpp$/) {
$dec !~ s/^\s*\class\s*//s;
if (!($dec =~ s/.*?://s)) {
$super = "";
} else {
$dec =~ s/\(.*//sg;
$dec =~ s/\{.*//sg;
$dec =~ s/^\s*//sg;
$dec =~ s/^public//g;
$dec =~ s/^private//g;
$dec =~ s/^protected//g;
$dec =~ s/^virtual//g;
$super = $dec;
}
}
$super =~ s/^\s*//;
$super =~ s/\s.*//;
print "$super is super\n" if ($localDebug);
return $super;
}
sub determineClassType {
my $lineCounter = shift;
my $apiOwner = shift;
my $inputLinesRef = shift;
my @inputLines = @$inputLinesRef;
my $classType = "unknown";
my $tempLine = "";
my $localDebug = 0;
do {
$tempLine = $inputLines[$lineCounter];
$lineCounter++;
} while (($tempLine !~ /class|\@class|\@interface|\@protocol|typedef\s+struct/) && ($lineCounter <= $
if ($tempLine =~ s/class\s//) {
$classType = "cpp";
}
if ($tempLine =~ s/typedef\s+struct\s//) {
$classType = "C"; }
if ($tempLine =~ s/(\@class|\@interface)\s//) {
if ($tempLine =~ /\(.*\)/ && ($1 ne "\@class")) {
$classType = "occCat"; } else {
$classType = "occ";
}
}
if ($tempLine =~ s/\@protocol\s//) {
$classType = "intf";
}
if ($lang eq "php") {
$classType = "php";
}
if ($lang eq "java") {
$classType = "java";
}
print "determineClassType: returning $classType\n" if ($localDebug);
if ($classType eq "unknown") {
print "Bogus class ($tempLine)\n";
}
$HeaderDoc::sublang = $classType;
return $classType;
}
sub processClassComment {
my $apiOwner = shift;
my $headerObj = $apiOwner;
my $rootOutputDir = shift;
my $fieldArrayRef = shift;
my @fields = @$fieldArrayRef;
my $classType = shift;
my $filename = $HeaderDoc::headerObject->filename();
my $linenum = shift;
SWITCH: {
($classType eq "php" ) && do { $apiOwner = HeaderDoc::CPPClass->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "java" ) && do { $apiOwner = HeaderDoc::CPPClass->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "cpp" ) && do { $apiOwner = HeaderDoc::CPPClass->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "cppt" ) && do { $apiOwner = HeaderDoc::CPPClass->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "occ") && do { $apiOwner = HeaderDoc::ObjCClass->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "occCat") && do { $apiOwner = HeaderDoc::ObjCCategory->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "intf") && do { $apiOwner = HeaderDoc::ObjCProtocol->new; $apiOwner->filename($filename); last SWITCH; };
($classType eq "C") && do { $apiOwner = HeaderDoc::CPPClass->new; $apiOwner->filename($filename); $apiOwner->CClass(1); last SWITCH; };
print "Unknown type ($classType). known: classes (ObjC and C++), ObjC categories and protocols\n";
}
$apiOwner->linenum($linenum);
$apiOwner->apiOwner($HeaderDoc::currentClass);
$HeaderDoc::currentClass = $apiOwner;
if ($xml_output) {
$apiOwner->outputformat("hdxml");
} else {
$apiOwner->outputformat("html");
}
$apiOwner->headerObject($headerObj);
$apiOwner->outputDir($rootOutputDir);
foreach my $field (@fields) {
SWITCH: {
($field =~ /^\/\*\!/) && do {last SWITCH;}; (($lang eq "java") && ($field =~ /^\s*\/\*\*/)) && do {last SWITCH;}; ($field =~ s/^(class|interface|template)(\s+)/$2/) &&
do {
my ($name, $disc);
my $filename = $HeaderDoc::headerObject->filename();
($name, $disc) = &getAPINameAndDisc($field);
my $classID = ref($apiOwner);
$apiOwner->name($name);
$apiOwner->filename($filename);
if (length($disc)) {$apiOwner->discussion($disc);};
$functionGroup = "";
$HeaderDoc::globalGroup = "";
last SWITCH;
};
($field =~ s/^see(also|)(\s+)/$2/) &&
do {
$apiOwner->see($field);
};
($field =~ s/^protocol(\s+)/$1/) &&
do {
my ($name, $disc);
my $filename = $HeaderDoc::headerObject->filename();
($name, $disc) = &getAPINameAndDisc($field);
$apiOwner->name($name);
$apiOwner->filename($filename);
if (length($disc)) {$apiOwner->discussion($disc);};
$functionGroup = "";
$HeaderDoc::globalGroup = "";
last SWITCH;
};
($field =~ s/^category(\s+)/$1/) &&
do {
my ($name, $disc);
my $filename = $HeaderDoc::headerObject->filename();
($name, $disc) = &getAPINameAndDisc($field);
$apiOwner->name($name);
$apiOwner->filename($filename);
if (length($disc)) {$apiOwner->discussion($disc);};
$functionGroup = "";
$HeaderDoc::globalGroup = "";
last SWITCH;
};
($field =~ s/^templatefield(\s+)/$1/) && do {
$field =~ s/^\s+|\s+$//g;
$field =~ /(\w*)\s*(.*)/s;
my $fName = $1;
my $fDesc = $2;
my $fObj = HeaderDoc::MinorAPIElement->new();
$fObj->linenum($linenum);
$fObj->apiOwner($apiOwner);
$fObj->outputformat($apiOwner->outputformat);
$fObj->name($fName);
$fObj->discussion($fDesc);
$apiOwner->addToFields($fObj);
last SWITCH;
};
($field =~ s/^super(class|)(\s+)/$2/) && do { $apiOwner->attribute("Superclass", $field, 0); $apiOwner->explicitSuper(1); last SWITCH; };
($field =~ s/^throws(\s+)/$1/) && do {$apiOwner->throws($field); last SWITCH;};
($field =~ s/^exception(\s+)/$1/) && do {$apiOwner->throws($field); last SWITCH;};
($field =~ s/^abstract(\s+)/$1/) && do {$apiOwner->abstract($field); last SWITCH;};
($field =~ s/^discussion(\s+)/$1/) && do {$apiOwner->discussion($field); last SWITCH;};
($field =~ s/^availability(\s+)/$1/) && do {$apiOwner->availability($field); last SWITCH;};
($field =~ s/^since(\s+)/$1/) && do {$apiOwner->availability($field); last SWITCH;};
($field =~ s/^author(\s+)/$1/) && do {$apiOwner->attribute("Author", $field, 0); last SWITCH;};
($field =~ s/^version(\s+)/$1/) && do {$apiOwner->attribute("Version", $field, 0); last SWITCH;};
($field =~ s/^deprecated(\s+)/$1/) && do {$apiOwner->attribute("Deprecated", $field, 0); last SWITCH;};
($field =~ s/^version(\s+)/$1/) && do {$apiOwner->attribute("Version", $field, 0); last SWITCH;};
($field =~ s/^updated(\s+)/$1/) && do {$apiOwner->updated($field); last SWITCH;};
($field =~ s/^attribute(\s+)/$1/) && do {
my ($attname, $attdisc) = &getAPINameAndDisc($field);
if (length($attname) && length($attdisc)) {
$apiOwner->attribute($attname, $attdisc, 0);
} else {
warn "$filename:$linenum:Missing name/discussion for attribute\n";
}
last SWITCH;
};
($field =~ s/^attributelist(\s+)/$1/) && do {
$field =~ s/^\s*//s;
$field =~ s/\s*$//s;
my ($name, $lines) = split(/\n/, $field, 2);
$name =~ s/^\s*//s;
$name =~ s/\s*$//s;
$lines =~ s/^\s*//s;
$lines =~ s/\s*$//s;
if (length($name) && length($lines)) {
my @attlines = split(/\n/, $lines);
foreach my $line (@attlines) {
$apiOwner->attributelist($name, $line);
}
} else {
warn "$filename:$linenum:Missing name/discussion for attributelist\n";
}
last SWITCH;
};
($field =~ s/^attributeblock(\s+)/$1/) && do {
my ($attname, $attdisc) = &getAPINameAndDisc($field);
if (length($attname) && length($attdisc)) {
$apiOwner->attribute($attname, $attdisc, 1);
} else {
warn "$filename:$linenum:Missing name/discussion for attributeblock\n";
}
last SWITCH;
};
($field =~ s/^namespace(\s+)/$1/) && do {$apiOwner->namespace($field); last SWITCH;};
($field =~ s/^instancesize(\s+)/$1/) && do {$apiOwner->attribute("Instance Size", $field, 0); last SWITCH;};
($field =~ s/^performance(\s+)/$1/) && do {$apiOwner->attribute("Performance", $field, 1); last SWITCH;};
($field =~ s/^nestedclass(\s+)/$1/) && do {$apiOwner->attributelist("Nested Classes", $field); last SWITCH;};
($field =~ s/^coclass(\s+)/$1/) && do {$apiOwner->attributelist("Co-Classes", $field); last SWITCH;};
($field =~ s/^helper(class|)(\s+)/$2/) && do {$apiOwner->attributelist("Helper Classes", $field); last SWITCH;};
($field =~ s/^helps(\s+)/$1/) && do {$apiOwner->attribute("Helps", $field, 0); last SWITCH;};
($field =~ s/^classdesign(\s+)/$1/) && do {$apiOwner->attribute("Class Design", $field, 1); last SWITCH;};
($field =~ s/^dependency(\s+)/$1/) && do {$apiOwner->attributelist("Dependencies", $field); last SWITCH;};
($field =~ s/^ownership(\s+)/$1/) && do {$apiOwner->attribute("Ownership Model", $field, 1); last SWITCH;};
($field =~ s/^security(\s+)/$1/) && do {$apiOwner->attribute("Security", $field, 1); last SWITCH;};
($field =~ s/^whysubclass(\s+)/$1/) && do {$apiOwner->attribute("Reason to Subclass", $field, 1); last SWITCH;};
print "Unknown field in class comment: $field\n";
}
}
return $apiOwner;
}
sub processHeaderComment {
my $apiOwner = shift;
my $rootOutputDir = shift;
my $fieldArrayRef = shift;
my @fields = @$fieldArrayRef;
my $linenum = $apiOwner->linenum();
my $filename = $apiOwner->filename();
my $localDebug = 0;
foreach my $field (@fields) {
SWITCH: {
($field =~ /^\/\*\!/)&& do {last SWITCH;}; (($lang eq "java") && ($field =~ /^\s*\/\*\*/)) && do {last SWITCH;}; ($field =~ s/^see(also)\s+//) &&
do {
$apiOwner->see($field);
};
(($field =~ /^header\s+/) ||
($field =~ /^framework\s+/)) &&
do {
if ($field =~ s/^framework\s+//) {
$apiOwner->isFramework(1);
} else {
$field =~ s/^header\s+//;
}
my ($name, $disc);
($name, $disc) = &getAPINameAndDisc($field);
my $longname = $name; if (length($name)) {
print "Setting header name to $longname\n" if ($debugging);
$apiOwner->name($longname);
}
print "Discussion is:\n" if ($debugging);
print "$disc\n" if ($debugging);
if (length($disc)) {$apiOwner->discussion($disc);};
last SWITCH;
};
($field =~ s/^availability\s+//) && do {$apiOwner->availability($field); last SWITCH;};
($field =~ s/^since\s+//) && do {$apiOwner->availability($field); last SWITCH;};
($field =~ s/^author\s+//) && do {$apiOwner->attribute("Author", $field, 0); last SWITCH;};
($field =~ s/^version\s+//) && do {$apiOwner->attribute("Version", $field, 0); last SWITCH;};
($field =~ s/^deprecated\s+//) && do {$apiOwner->attribute("Deprecated", $field, 0); last SWITCH;};
($field =~ s/^version\s+//) && do {$apiOwner->attribute("Version", $field, 0); last SWITCH;};
($field =~ s/^attribute\s+//) && do {
my ($attname, $attdisc) = &getAPINameAndDisc($field);
if (length($attname) && length($attdisc)) {
$apiOwner->attribute($attname, $attdisc, 0);
} else {
warn "$filename:$linenum:Missing name/discussion for attribute\n";
}
last SWITCH;
};
($field =~ s/^attributelist\s+//) && do {
$field =~ s/^\s*//s;
$field =~ s/\s*$//s;
my ($name, $lines) = split(/\n/, $field, 2);
$name =~ s/^\s*//s;
$name =~ s/\s*$//s;
$lines =~ s/^\s*//s;
$lines =~ s/\s*$//s;
if (length($name) && length($lines)) {
my @attlines = split(/\n/, $lines);
foreach my $line (@attlines) {
$apiOwner->attributelist($name, $line);
}
} else {
warn "$filename:$linenum:Missing name/discussion for attributelist\n";
}
last SWITCH;
};
($field =~ s/^attributeblock\s+//) && do {
my ($attname, $attdisc) = &getAPINameAndDisc($field);
if (length($attname) && length($attdisc)) {
$apiOwner->attribute($attname, $attdisc, 1);
} else {
warn "$filename:$linenum:Missing name/discussion for attributeblock\n";
}
last SWITCH;
};
($field =~ s/^updated\s+//) && do {$apiOwner->updated($field); last SWITCH;};
($field =~ s/^abstract\s+//) && do {$apiOwner->abstract($field); last SWITCH;};
($field =~ s/^discussion\s+//) && do {$apiOwner->discussion($field); last SWITCH;};
($field =~ s/^copyright\s+//) && do { $apiOwner->headerCopyrightOwner($field); last SWITCH;};
($field =~ s/^meta\s+//) && do {$apiOwner->HTMLmeta($field); last SWITCH;};
($field =~ s/^language\s+//) && do {
SWITCH {
($field =~ /^\s*c\+\+\s*$/i) && do { $HeaderDoc::sublang = "cpp"; last SWITCH; };
($field =~ /^\s*objc\s*$/i) && do { $HeaderDoc::sublang = "occ"; last SWITCH; };
($field =~ /^\s*pascal\s*$/i) && do { $HeaderDoc::sublang = "pascal"; last SWITCH; };
($field =~ /^\s*perl\s*$/i) && do { $HeaderDoc::sublang = "perl"; last SWITCH; };
($field =~ /^\s*shell\s*$/i) && do { $HeaderDoc::sublang = "shell"; last SWITCH; };
($field =~ /^\s*php\s*$/i) && do { $HeaderDoc::sublang = "php"; last SWITCH; };
($field =~ /^\s*javascript\s*$/i) && do { $HeaderDoc::sublang = "javascript"; last SWITCH; };
($field =~ /^\s*java\s*$/i) && do { $HeaderDoc::sublang = "java"; last SWITCH; };
($field =~ /^\s*c\s*$/i) && do { $HeaderDoc::sublang = "C"; last SWITCH; };
{
warn("$filename:$linenum:Unknown language $field in header comment\n");
};
};
};
($field =~ s/^CFBundleIdentifier\s+//i) && do {$apiOwner->attribute("CFBundleIdentifier", $field, 0); last SWITCH;};
($field =~ s/^related\s+//i) && do {$apiOwner->attributelist("Related Headers", $field); last SWITCH;};
($field =~ s/^(compiler|)flag\s+//) && do {$apiOwner->attributelist("Compiler Flags", $field); last SWITCH;};
($field =~ s/^preprocinfo\s+//) && do {$apiOwner->attribute("Preprocessor Behavior", $field, 1); last SWITCH;};
($field =~ s/^whyinclude\s+//) && do {$apiOwner->attribute("Reason to Include", $field, 1); last SWITCH;};
($field =~ s/^ignore\s+//) && do { $field =~ s/\n//smg; push(@perHeaderIgnorePrefixes, $field); if (!($reprocess_input)) {$reprocess_input = 1;} print "ignoring $field" if ($localDebug); last SWITCH;};
warn("$filename:$linenum:Unknown field in header comment: $field\n");
}
}
return $apiOwner;
}
sub strip
{
my $filename = shift;
my $output_path = shift;
my $inputRef = shift;
my @inputLines = @$inputRef;
my $output_file = "$output_path$pathSeparator$filename";
if (-e $output_file) {
$output_file .= "-stripped";
print "WARNING: output file exists. Saving as\n\n";
print " $output_file\n\n";
print "instead.\n";
}
open(OUTFILE, ">$output_file") || die "Can't write $output_file.\n";
if ($^O =~ /MacOS/i) {MacPerl::SetFileInfo('R*ch', 'TEXT', "$output_file");};
my $inComment = 0;
my $text = "";
my $localDebug = 0;
foreach my $line (@inputLines) {
print "line $line\n" if ($localDebug);
print "inComment $inComment\n" if ($localDebug);
if (($line =~ /^\/\*\!/) || (($lang eq "java") && ($line =~ /^\s*\/\*\*/))) { $inComment = 1;
}
if ($inComment && ($line =~ /\*\//)) {
$inComment = 2;
}
if (!$inComment) { $text .= $line; }
if ($inComment == 2) {
$inComment = 0;
}
}
print OUTFILE $text;
close OUTFILE;
}
sub classLookAhead
{
my $lineref = shift;
my $inputCounter = shift;
my $lang = shift;
my $sublang = shift;
my @linearray = @{$lineref};
my $inComment = 0;
my $inILC = 0;
my $inAt = 0;
my $localDebug = 0;
my ($sotemplate, $eotemplate, $operator, $soc, $eoc, $ilc, $sofunction,
$soprocedure, $sopreproc, $lbrace, $rbrace, $unionname, $structname,
$typedefname, $varname, $constname, $structisbrace, $macronameref)
= parseTokens($lang, $sublang);
my $nametoken = "";
my $typetoken = "";
while ($inputCounter < scalar(@linearray)) {
my $line = $linearray[$inputCounter];
my @parts = split(/((\/\*|\/\/|\*\/|\W))/, $line);
print "CLALINE: $line\n" if ($localDebug);
foreach my $token (@parts) {
if (!length($token)) {
next;
print "CLA:notoken\n" if ($localDebug);
} elsif ($token eq "$soc") {
$inComment = 1;
print "CLA:soc\n" if ($localDebug);
} elsif ($token eq "$ilc") {
$inILC = 1;
print "CLA:ilc\n" if ($localDebug);
} elsif ($token eq "$eoc") {
$inComment = 0;
print "CLA:eoc\n" if ($localDebug);
} elsif ($token =~ /\s+/) {
print "CLA:whitespace\n" if ($localDebug);
} else {
print "CLA:text\n" if ($localDebug);
if ($token =~ /\;/) {
next;
print "CLA:semi\n" if ($localDebug);
} elsif ($token =~ /\@/) {
$inAt = 1;
print "CLA:inAt\n" if ($localDebug);
} elsif (!$inAt && $token =~ /class/) {
print "CLA:cpp_or_java_class\n" if ($localDebug);
$typetoken = "class";
} elsif ($inAt && $token =~ /(class|interface|protocol)/) {
print "CLA:occ_$1\n" if ($localDebug);
$typetoken = $1;
} else {
if ($typetoken eq "") {
print "CLA:NOTACLASS:\"$token\"\n" if ($localDebug);
return ();
} else {
print "CLA:CLASSNAME:\"$token\"\n" if ($localDebug);
return ($token, $typetoken);
}
}
}
}
$inputCounter++; $inILC = 0;
}
warn "ClassLookAhead ran off EOF\n";
return ();
}
sub printVersionInfo {
my $av = HeaderDoc::APIOwner->VERSION();
my $hev = HeaderDoc::HeaderElement->VERSION();
my $hv = HeaderDoc::Header->VERSION();
my $cppv = HeaderDoc::CPPClass->VERSION();
my $objcv = HeaderDoc::ObjCClass->VERSION();
my $objcprotocolv = HeaderDoc::ObjCProtocol->VERSION();
my $fv = HeaderDoc::Function->VERSION();
my $mv = HeaderDoc::Method->VERSION();
my $tv = HeaderDoc::Typedef->VERSION();
my $sv = HeaderDoc::Struct->VERSION();
my $cv = HeaderDoc::Constant->VERSION();
my $vv = HeaderDoc::Var->VERSION();
my $ev = HeaderDoc::Enum->VERSION();
my $uv = HeaderDoc::Utilities->VERSION();
my $me = HeaderDoc::MinorAPIElement->VERSION();
print "----------------------------------------------------\n";
print "\tHeaderDoc version $VERSION.\n";
print "\tModules:\n";
print "\t\tAPIOwner - $av\n";
print "\t\tHeaderElement - $hev\n";
print "\t\tHeader - $hv\n";
print "\t\tCPPClass - $cppv\n";
print "\t\tObjClass - $objcv\n";
print "\t\tObjCProtocol - $objcprotocolv\n";
print "\t\tFunction - $fv\n";
print "\t\tMethod - $mv\n";
print "\t\tTypedef - $tv\n";
print "\t\tStruct - $sv\n";
print "\t\tConstant - $cv\n";
print "\t\tEnum - $ev\n";
print "\t\tVar - $vv\n";
print "\t\tMinorAPIElement - $me\n";
print "\t\tUtilities - $uv\n";
print "----------------------------------------------------\n";
}