package HeaderDoc::BlockParse;
$HeaderDoc::includeFunctionContents = 0;
BEGIN {
foreach (qw(Mac::Files)) {
$MOD_AVAIL{$_} = eval "use $_; 1";
}
}
use Carp qw(cluck);
use HeaderDoc::TypeHelper;
use Exporter;
foreach (qw(Mac::Files Mac::MoreFiles)) {
eval "use $_";
}
$HeaderDoc::OptionalOrRequired = "";
@ISA = qw(Exporter);
@EXPORT = qw(blockParse nspaces blockParseOutside getAndClearCPPHash cpp_remove buildCommentFromFields bracematching peekmatch cpp_add_cl pbs);
@EXPORT_OK = qr(blockParseReturnState);
use HeaderDoc::Utilities qw(findRelativePath safeName printArray printHash parseTokens isKeyword warnHDComment classTypeFromFieldAndBPinfo casecmp addAvailabilityMacro printFields objectForUID peek);
use HeaderDoc::HashObject;
use HeaderDoc::PythonParse qw(pythonParse);
my $cpp_debug_file = "";
$cpp_debug_file = "/tmp/cpp_debug";
my $cpp_debug_lastfile = "";
use strict;
use vars qw($VERSION @ISA);
use File::Basename qw(basename);
$HeaderDoc::BlockParse::VERSION = '$Revision: 1368568932 $';
my $isMacOS;
my $pathSeparator;
if ($^O =~ /MacOS/io) {
$pathSeparator = ":";
$isMacOS = 1;
} else {
$pathSeparator = "/";
$isMacOS = 0;
}
my %CPP_HASH = ();
my %CPP_ARG_HASH = ();
my $cppDebugDefault = 0;
my $cppDebug = 0;
my $cppAddDebug = 0;
my $cppDebugFromToken = "";
my $nestedcommentwarn = 0;
my $warnAllMultipleDefinitions = 1;
my $modules_are_special = 1;
$HeaderDoc::useParmNameForUnlabeledParms = 1;
$HeaderDoc::inputCounterDebug = 0;
my $tempDebug = 1;
$HeaderDoc::hideIDLAttributes = 1;
sub cpp_subparse($);
sub getLangAndSublangFromClassType
{
my $classtype = shift;
my $outerlang = shift;
my $outersublang = shift;
if ($outerlang ne "C" && $outerlang ne "Csource") {
return ($outerlang, $outersublang);
}
my $lang = "C";
my $sublang = "C";
if ($classtype =~ /\@/) {
$sublang = "occ";
} elsif ($classtype =~ /class/) {
$sublang = "cpp";
} elsif ($classtype =~ /interface/) {
$sublang = "IDL";
} elsif ($classtype =~ /module/) {
$sublang = "IDL";
}
return ($lang, $sublang);
}
sub peekmatch
{
my $ref = shift;
my $lang = shift;
my $fullpath = shift;
my $linenum = shift;
my @stack = @{$ref};
my $tos = pop(@stack);
push(@stack, $tos);
if (!$tos) {
return "";
}
return bracematching($tos, $lang, $fullpath, $linenum);
}
sub bracematching
{
my $tos = shift;
my $lang = shift;
my $calledByParser = 0;
my $fullpath = "";
my $linenum = "";
if (@_) {
$calledByParser = 1;
$fullpath = shift;
$linenum = shift;
}
SWITCH: {
($tos eq "{") && do {
return "}";
};
($tos eq "#") && do {
return "#";
};
($tos eq "(") && do {
return ")";
};
($tos eq "/") && do {
return "/";
};
($tos eq "|") && do {
return "|";
};
($tos eq "'") && do {
return "'";
};
($tos eq "\"") && do {
return "\"";
};
($tos eq "`") && do {
return "`";
};
($tos eq "<") && do {
return ">";
};
($tos eq "[") && do {
return "]";
};
($tos eq "\@interface") && do {
return "\@end";
};
($tos eq "\@implementation") && do {
return "\@end";
};
($tos eq "\@protocol") && do {
return "\@end";
};
(($lang eq "applescript") && $tos =~ /(if|repeat|try|tell)/) && do {
return "end";
};
(($lang eq "ruby") && $tos =~ /(for|while|if|until|begin)/) && do {
return "end";
};
{
if ($calledByParser) {
warn "$fullpath:$linenum: warning: Unknown block delimiter \"$tos\". Please file a bug.\n";
return $tos;
}
return "";
};
}
}
sub blockParse
{
my $fullpath = shift;
my $fileoffset = shift;
my $inputLinesRef = shift;
my $inputCounter = shift;
my $argparse = shift;
my $ignoreref = shift;
my $perheaderignoreref = shift;
my $perheaderignorefuncmacrosref = shift;
my $keywordhashref = shift;
my $case_sensitive = shift;
my $lang = shift;
my $sublang = shift;
if (!$lang) {
print STDERR "WARNING: Old API use detected. Please update your\ncode to call blockParse with a lang argument.\nThis will break in a future version of HeaderDoc.\n";
cluck("Backtrace:\n");
$lang = $HeaderDoc::lang;
}
if (!$sublang) {
$sublang = $HeaderDoc::sublang;
print STDERR "WARNING: Old API use detected. Please update your\ncode to call blockParse with a sublang argument.\nThis will break in a future version of HeaderDoc.\n";
cluck("Backtrace:\n");
}
if ($lang eq "python") {
return pythonParse($fullpath, $fileoffset, $inputLinesRef, $inputCounter,
$argparse, $ignoreref, $perheaderignoreref, $perheaderignorefuncmacrosref,
$keywordhashref, $case_sensitive, $lang, $sublang);
}
my $apwarn = 0;
if ($argparse && $apwarn) {
print STDERR "argparse\n";
}
my @inputLines = @{$inputLinesRef};
my $declaration = "";
my $publicDeclaration = "";
my $retDebug = 0;
my $localDebug = 0 || $HeaderDoc::fileDebug;
my $operatorDebug = 0;
my $listDebug = 0;
my $parseDebug = 0 || $HeaderDoc::fileDebug;
my $sodDebug = 0 || $HeaderDoc::fileDebug;
my $valueDebug = 0;
my $parmDebug = 0;
my $bitfieldDebug = 0;
my $cbnDebug = 0;
my $macroDebug = 0;
my $apDebug = 0;
my $tsDebug = 0;
my $treeDebug = 0;
my $ilcDebug = 0;
my $regexpDebug = 0; my $parserStackDebug = 0 || $HeaderDoc::fileDebug;
my $braceDebug = 0 || $HeaderDoc::fileDebug;
my $hangDebug = 0;
my $offsetDebug = 0;
my $classDebug = 0; my $gccAttributeDebug = 0; my $occMethodNameDebug = 0;
my $moduleDebug = 0; my $lineDebug = 0 || $HeaderDoc::fileDebug; my $liteDebug = 0 || $HeaderDoc::fileDebug; my $tokenDebug = 0;
my $functionContentsDebug = 0;
my $continueDebug = 0;
my $parserStateInsertDebug = 0;
my $rubyDebug = 0;
my $asDebug = 0;
my $reMarkDebug = 0;
$cppDebug = $cppDebugDefault ? $cppDebugDefault : $HeaderDoc::fileDebug;
my $continue = 1; my $continue_no_return = 0; my $callback_typedef_and_name_on_one_line = 1; my $treeNest = 0; my $sethollow = 0;
my $setNoInsert = 0;
my $treepart = "";
if ($argparse && $tsDebug) { $tsDebug = 0; }
my $treeTop = HeaderDoc::ParseTree->new();
my $treeCur = $treeTop; my $treeSkip = 0; my $treePopOnNewLine = 0; my @treeStack = ();
$treeCur = $treeCur->addChild("");
$treeTop = $treeCur;
my $lastACS = "";
if ($argparse && $apDebug) {
$localDebug = 1;
$retDebug = 1;
$listDebug = 1;
$parseDebug = 1;
$sodDebug = 1;
$valueDebug = 1;
$parmDebug = 1;
$cbnDebug = 1;
$macroDebug = 1;
$tsDebug = 1;
$treeDebug = 1;
$ilcDebug = 1;
$regexpDebug = 1;
}
my $spaceDebug = 0;
if ($localDebug || $apDebug || $liteDebug || $parseDebug) {
print STDERR "ENTERED BLOCKPARSE\n";
}
my $disable_cpp = 0;
if ($argparse && ($localDebug || $apDebug || $liteDebug)) {
print STDERR "ARGPARSE MODE!\n";
print STDERR "IPC: $inputCounter\nNLINES: ".$#inputLines."\n";
cluck("Call backtrace\n");
}
print STDERR "INBP\n" if ($localDebug);
if ($argparse) {
$disable_cpp = 1;
}
if (($lang ne "C" && $lang ne "Csource") || $sublang eq "php") { $disable_cpp = 1;
}
print STDERR "INITIAL LANG: $lang INITIAL SUBLANG: $sublang\n" if ($localDebug);
my $parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->setHollowWithLineNumbers($treeTop, $fileoffset, $inputCounter);
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = 0; my @parserStack = ();
my @braceStack = ();
my @parsedParamParseStack = ();
my $inPrivateParamTypes = 0; my $inPType = 0; my $inRegexp = 0; my $leavingRegexp = 0; my $inRegexpFirstPart = 0; my $inRegexpCharClass = 0; my $regexpNoInterpolate = 0; my $inRegexpTrailer = 0; my $hollowskip = 0;
my $ppSkipOneToken = 0;
my @regexpStack = ();
my %parseTokens = %{parseTokens($lang, $sublang)};
my $labelregexp = $parseTokens{labelregexp};
my $classregexp = $parseTokens{classregexp};
my $classbraceregexp = $parseTokens{classbraceregexp};
my $classclosebraceregexp = $parseTokens{classclosebraceregexp};
my $accessregexp = $parseTokens{accessregexp};
my $requiredregexp = $parseTokens{requiredregexp};
my $moduleregexp = $parseTokens{moduleregexp};
my $regexppattern = $parseTokens{regexppattern};
my $singleregexppattern = $parseTokens{singleregexppattern};
my $regexpfirstcharpattern = $parseTokens{regexpfirstcharpattern};
my $regexpcharpattern = $parseTokens{regexpcharpattern};
my $regexpAllowedAfter = $parseTokens{regexpAllowedAfter};
my $TCLregexpcommand = $parseTokens{TCLregexpcommand};
if ($argparse && $lang eq "applescript") {
$parseTokens{assignmentwithcolon} = 2;
}
my $macrore_pound = macroRegexpFromList($parseTokens{macronames}, 1);
my $macrore_nopound = macroRegexpFromList($parseTokens{macronames}, 2);
print STDERR "MACRORE_POUND: \"$macrore_pound\"\n" if ($localDebug || $parseDebug);
print STDERR "MACRORE_NOPOUND: \"$macrore_nopound\"\n" if ($localDebug || $parseDebug);
if ($parseDebug) {
print STDERR "SOT: $parseTokens{sotemplate} EOF: $parseTokens{eotemplate} OP: $parseTokens{operator} SOC: $parseTokens{soc} EOC: $parseTokens{eoc} ILC: $parseTokens{ilc} ILC_B: $parseTokens{ilc_b}\n";
print STDERR "SOFUNC: $parseTokens{sofunction} SOPROC: $parseTokens{soprocedure} SOPREPROC: $parseTokens{sopreproc} LBRACE: $parseTokens{lbrace} RBRACE: $parseTokens{rbrace}\n";
print STDERR "UNION: $parseTokens{unionname} STRUCT: $parseTokens{structname} TYPEDEF: $parseTokens{typedefname} VAR: $parseTokens{varname} CONST: $parseTokens{constname}\n";
print STDERR "STRUCTISBRACE: $parseTokens{structisbrace} MACRONAMEREF: $parseTokens{macronames} CLASSRE: $classregexp\n";
print STDERR "CLASSBRACERE: $classbraceregexp CLASSCLOSEBRACERE: $classclosebraceregexp ACCESSRE: $accessregexp\n";
print STDERR "MODULERE: $moduleregexp\n";
}
if ($lang eq "perl" || $lang eq "shell" || $lang eq "tcl") {
if ($lang eq "perl") {
}
}
my $pascal = 0; my $ruby = 0;
if ($lang eq "pascal") { $pascal = 1; }
if ($lang eq "ruby") { $ruby = 1; }
my $lastchar = ""; my $lastnspart = ""; my $lasttoken = ""; my $prespace = 0; my $prespaceadjust = 0; my $scratch = ""; my $curline = ""; my $curstring = ""; my $continuation = 0; my $forcenobreak = 0; my $occspace = 0; my $parsedParam = ""; my $postPossNL = 0;
my $asConcat = "";
my $pushParserStateAfterToken = 0;
my $pushParserStateAfterWordToken = 0;
my $pushParserStateAtBrace = 0;
my $occPushParserStateOnWordTokenAfterNext = 0;
if (!$disable_cpp && (1 || $HeaderDoc::enable_cpp)) {
if ($cpp_debug_file) {
if (basename($fullpath) ne $cpp_debug_lastfile) {
open(CPP_DEBUG_FILE, ">>$cpp_debug_file");
print CPP_DEBUG_FILE "DUMPING CPP INFORMATION FOR $fullpath\n";
close(CPP_DEBUG_FILE);
my $filename = basename($fullpath);
$cpp_debug_lastfile = $filename;
}
}
}
$HeaderDoc::hidetokens = 0;
my $nlines = $#inputLines;
my $incrementoffsetatnewline = 0;
print STDERR "INCOMING INPUTCOUNTER: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
print STDERR "IL[0]: ".$inputLines[0]."\n" if ($hangDebug);
while ($continue && ($inputCounter <= $nlines)) {
print STDERR "IC: $inputCounter NLINES: $nlines\n" if ($hangDebug);
$HeaderDoc::CurLine = $inputCounter + $fileoffset;
my $line = $inputLines[$inputCounter++];
print STDERR "GOT LINE: $line\n" if (($localDebug && $apDebug) || $lineDebug || $HeaderDoc::inputCounterDebug);
print STDERR "INCREMENTED INPUTCOUNTER [1]\n" if ($HeaderDoc::inputCounterDebug);
my @parts = ();
$line =~ s/\s*$//go;
$line .= "\n";
if ($lang eq "C" && $sublang eq "IDL") {
if ($line =~ /cpp_quote\s*\(\s*\"(.*)\"\s*\)\s*$/) {
print STDERR "CHANGED LINE FROM \"$line\" to " if ($localDebug || $liteDebug);
$line = $1."\n";
$line =~ s/\\\"/"/sg;
print STDERR "\"$line\"\n" if ($localDebug || $liteDebug);
}
}
print STDERR "LINE[$inputCounter] : $line\n" if ($offsetDebug);
# The tokenizer
if ($lang eq "perl") {
@parts = split(/(->|=>|\&\&|\|\||"|'|\#|\{|\}|\(|\)|\s|;;|;|::|\\|\<\<|\W)/, $line);
} elsif ($lang eq "shell") {
@parts = split(/("|'|\ } elsif ($lang eq "tcl") {
@parts = split(/("|'|\#|\{|\}|\(|\)|\s|;|\\|::|\/\*|\*\/|\W)/, $line);
} elsif ($ruby) {
@parts = split(/(=begin|=end|\%\{|\%\/|\%Q\{|\<\<\-|"|'|\/\/|\/\*|\*\/|::|\-\-|\+\+|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\^|\W)/, $line);
} elsif ($lang eq "applescript") {
# Easier to have the tokenizer combine these multi-word tokens than
# to do it later.
# Because this regexp terrifies mere mortals, here's an explanation:
@parts = split(/((?<=\s)apart\s+from(?!\s)|(?<=\s)aside\s+from(?!\s)|(?<=\s)instead\s+of(?!\s)|(?<=\s)out\s+of(?!\s)|"|'|\/\/|\(\*|\*\)|::|\-\-|\+\+|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\^|\W)/, $line);
} else {
@parts = split(/("|'|\/\/|\/\*|\*\/|\.\.\.|::|\-\-|\+\+|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\^|\W)/, $line);
}
# See note about similar block below. This block is for fixing the
# "missing newline" problem, which otherwise would cause line numbers
# to sometimes be wrong.
push(@parts, "BOGUSBOGUSBOGUSBOGUSBOGUS");
my $xpart = "";
foreach my $nextxpart (@parts) {
if (!length($nextxpart)) { next; }
if (!length($xpart)) { $xpart = $nextxpart; next; }
if ($xpart eq "\n" && $nextxpart ne "BOGUSBOGUSBOGUSBOGUSBOGUS") {
print STDERR "FOUND EXTRA NEWLINE\n" if ($offsetDebug);
# $fileoffset++;
$incrementoffsetatnewline++;
}
$xpart = $nextxpart;
}
pop(@parts);
$parserState->{inInlineComment} = 0;
print STDERR "inInlineComment -> 0\n" if ($ilcDebug);
# warn("line $inputCounter\n");
if ($localDebug || $cppDebug || $spaceDebug || $cppDebugFromToken) {
foreach my $partlist (@parts) {
print STDERR "PARTLIST: \"$partlist\"\n";
if ($partlist eq $cppDebugFromToken && length($cppDebugFromToken)) {
$cppDebug = 1; $parseDebug = 1; $macroDebug = 1;
}
}
}
# We have to do the C preprocessing work up front because token substitution
# must occur prior to actual parsing in order to do any good. This block does
# the work.
my $cpp_in_argparse = 0;
if (!$disable_cpp && (1 || $HeaderDoc::enable_cpp)) {
my $newrawline = "";
my $incppargs = 0;
my $cppstring = "";
my $cppname = "";
my $lastcpppart = "";
my @cppargs = ();
my $inChar = 0; my $inString = 0; my $inComment = $parserState->{inComment}; my $inSLC = $parserState->{inInlineComment};
my $inParen = 0;
my $inMacro = $parserState->{inMacro};
my $inCPPSpecial = $parserState->{inMacro} || $parserState->{inMacroLine};
my $inMacroTail = 0;
if ($parserState->{sodname} && ($parserState->{sodname} ne "")) {
$inMacroTail = 1;
}
print STDERR "INMACROTAIL: $inMacroTail\n" if ($cppDebug);
my @cpptrees;
my $cpptreecur = HeaderDoc::ParseTree->new();
my $cpptreetop = $cpptreecur;
my $definename = $parseTokens{definename};
print STDERR "CHECK LINE $line\n" if ($cppDebug || $hangDebug);
if ($line =~ /^\s*#(include|import)\s(.*)$/) {
print STDERR "IS INCLUDE OR IMPORT\n" if ($cppDebug);
my $token = $1;
my $rest = $2;
$rest =~ s/^\s*//s;
$rest =~ s/\s*$//s;
if ($rest !~ s/^\<(.*)\>$/$1/s) {
$rest =~ s/^\"(.*)\"$/$1/s;
}
my $filename = basename($rest);
if ($HeaderDoc::HeaderFileCPPHashHash{$filename}) {
my $includehash = HeaderDoc::IncludeHash->new();
$includehash->{FILENAME} = $filename;
$includehash->{LINENUM} = $inputCounter + $fileoffset;
$includehash->{HASHREF} = $HeaderDoc::HeaderFileCPPHashHash{$filename};
push(@HeaderDoc::cppHashList, $includehash);
# print STDERR "PUSH HASH\n";
push(@HeaderDoc::cppArgHashList, $HeaderDoc::HeaderFileCPPArgHashHash{$filename});
}
} elsif ($line =~ /^\s*$definename\s+/) {
print STDERR "IS DEFINE\n" if ($cppDebug);
# print STDERR "inMacro -> 1\n";
# print STDERR "inMacro -> 1\n" if ($macroDebug || $cppDebug);
# This is a throwaway line.
$inMacro = 1;
}
if ($macrore_pound ne "" && $line =~ /^\s*\#\s*$macrore_pound\s+/) {
print STDERR "CPPSPECIAL -> 1\n" if ($macroDebug || $cppDebug);
$inCPPSpecial = 1;
}
my $cppleaddebug = 0;
do {
my $pos = 0;
my $dropargs = 0;
print STDERR "ENTERING CPP LOOP\n" if ($hangDebug);
while ($pos < scalar(@parts)) {
my $part = $parts[$pos];
my $noCPPThisToken = 0;
print STDERR "IN CPP LOOP. PART IS $part INCPPARGS: $incppargs\n" if ($cppDebug || $hangDebug);
if (length($part)) {
if (!$inChar && !$inString && !$inComment && !$inSLC) {
if ($parserState->{NEXTTOKENNOCPP} == 1) {
print STDERR "In an \"if\" block (NTNCPP=1)\n" if ($cppDebug);
# We're in an "if" block.
if ($part eq "defined") {
$parserState->{NEXTTOKENNOCPP} = 3;
}
} elsif ($parserState->{NEXTTOKENNOCPP} == 2) {
print STDERR "In an \"ifdef/ifndef\" block\n" if ($cppDebug);
if ($part !~ /(\s|\()/) {
$parserState->{NEXTTOKENNOCPP} = 0;
$noCPPThisToken = 1;
}
} elsif ($parserState->{NEXTTOKENNOCPP} == 3) {
print STDERR "In an \"if\" block (NTNCPP=3)\n" if ($cppDebug);
if ($part !~ /(\s|\()/) {
$parserState->{NEXTTOKENNOCPP} = 1;
$noCPPThisToken = 1;
}
}
if ($inCPPSpecial && $part =~ /^(ifdef|ifndef)$/) {
print STDERR "CPPSpecial: ifdef/ifndef\n" if ($cppDebug);
$parserState->{NEXTTOKENNOCPP} = 2;
} elsif ($inCPPSpecial && $part =~ /^if$/) {
print STDERR "CPPSpecial: if\n" if ($cppDebug);
$parserState->{NEXTTOKENNOCPP} = 1;
}
}
print STDERR "TOKEN: $part NEXTTOKENNOCPP: ".$parserState->{NEXTTOKENNOCPP}." INMACRO: $inMacro INCPPSPECIAL: $inCPPSpecial\n" if ($cppleaddebug || $macroDebug || $cppDebug);
print STDERR "CPPLEADPART: $part\n"if ($cppleaddebug);
if (!$inString && !$inChar) {
if ($inComment && $part eq $parseTokens{eoc}) {
print STDERR "EOC\n"if ($cppleaddebug);
$inComment = 0;
} elsif ($inSLC && $part =~ /[\r\n]/) {
print STDERR "EOSLC\n"if ($cppleaddebug);
$inSLC = 0;
} elsif (!$inSLC && $part eq $parseTokens{soc}) {
print STDERR "SOC\n"if ($cppleaddebug);
$inComment = 1;
} elsif (!$inComment && ($part eq $parseTokens{ilc} || $part eq $parseTokens{ilc_b})) {
print STDERR "INSLC\n"if ($cppleaddebug);
$inSLC = 1;
}
}
my $skip = 0;
if (!$incppargs) {
my $newpart = $part;
my $hasargs = 0;
if (!$inComment && !$inSLC && !$noCPPThisToken) {
my $tempstring = "";
($newpart, $hasargs, $tempstring) = cpp_preprocess($part, $HeaderDoc::CurLine);
if ($hasargs == 2 && $inMacro) {
$newpart = $part;
$hasargs = 0;
}
if ($inMacro && !$inMacroTail) {
$newpart = $part;
$hasargs = 0;
}
}
if ($hasargs) {
print STDERR "HAS ARGS!\n" if ($cppDebug);
$incppargs = 1;
$cppname = $part;
if ($hasargs == 2) {
$dropargs = 1;
print STDERR "Dropping arguments for ignored macro \"$part\"\n" if ($cppDebug);
}
} else {
my $newpartnl = $newpart;
my $newpartnlcount = ($newpartnl =~ tr/\n//);
my $partnl = $part;
my $partnlcount = ($partnl =~ tr/\n//);
my $nlchange = ($newpartnlcount - $partnlcount);
print STDERR "NLCHANGE: $nlchange (FILEOFFSET = $fileoffset)\n" if ($offsetDebug);
$fileoffset -= $nlchange;
if ($inMacro) {
if ($newpart ne $part) {
print STDERR "CHANGING NEWPART FROM \"$newpart\" TO " if ($cppDebug);
$newpart =~ s/^\s*/ /s;
$newpart =~ s/\s*$//s;
$newpart =~ s/(.)\n/$1 \\\n/sg;
$newpart =~ s/\\$/ /s;
print STDERR "$newpart\n" if ($cppDebug);
}
}
$newrawline .= $newpart;
}
} elsif ($incppargs == 1) {
if ($part eq "(") {
$incppargs = 3;
$inParen++;
}
} elsif ($incppargs == 3) {
if ($part eq '\\') {
if (!$inMacro && ($lastcpppart eq '\\')) { $lastcpppart = ""; } } elsif ($part eq '"') {
if ($lastcpppart ne '\\') {
if (!$inChar && !$inComment && !$inSLC) {
$inString = !$inString;
}
}
$lastcpppart = $part;
} elsif ($part eq "'") {
if ($lastcpppart ne '\\') {
if (!$inString && !$inComment && !$inSLC) {
$inChar = !$inChar;
}
}
$lastcpppart = $part;
} elsif (!$inChar && !$inString && !$inComment && !$inSLC) {
if ($part eq "(") {
$cpptreecur = $cpptreecur->next(HeaderDoc::ParseTree->new());
$cpptreecur->token($part);
$skip = 1;
$inParen++;
push(@cpptrees, $cpptreecur);
$cpptreecur = $cpptreecur->firstchild(HeaderDoc::ParseTree->new());
} elsif ($part eq ")") {
$inParen--;
if (scalar(@cpptrees)) {
$cpptreecur = pop(@cpptrees);
while ($cpptreecur && $cpptreecur->next()) {
$cpptreecur = $cpptreecur->next();
}
}
if (!$inParen) {
push(@cppargs, $cpptreetop);
$cppstring = "";
$cpptreetop = HeaderDoc::ParseTree->new();
$cpptreecur = $cpptreetop;
$skip = 1;
$incppargs = 0;
if (!$dropargs) {
print STDERR "CALLING ARGPARSE FROM blockParse() [1].\n" if ($cppDebug);
my $addon = cpp_argparse($cppname, $HeaderDoc::CurLine, \@cppargs);
if ($inMacro) {
print STDERR "CHANGING ADDON FROM:\n\"$addon\"\nTO:\n" if ($cppDebug);
$addon =~ s/^\s*/ /s;
$addon =~ s/\s*$//s;
$addon =~ s/(.)\n/$1 \\\n/sg;
$addon =~ s/\\$/ /s;
print STDERR "\"$addon\"\n" if ($cppDebug);
}
$newrawline .= $addon;
}
$dropargs = 0;
}
} elsif (($inParen == 1) && (!$inChar && !$inString && !$inComment && !$inSLC) && ($part eq ",")) {
push(@cppargs, $cpptreetop);
$cpptreetop = HeaderDoc::ParseTree->new();
$cpptreecur = $cpptreetop;
$cppstring = "";
$skip = 1;
} elsif (($part =~ /\s/) && (!$inParen)) {
$incppargs = 0;
if (!$dropargs) {
print STDERR "CALLING ARGPARSE FROM blockParse() [2].\n" if ($cppDebug);
my $addon = cpp_argparse($cppname, $HeaderDoc::CurLine, \@cppargs);
if ($inMacro) {
print STDERR "CHANGING ADDON FROM \"$addon\" TO " if ($cppDebug);
$addon =~ s/^\s*/ /s;
$addon =~ s/\s*$//s;
$addon =~ s/(.)\n/$1 \\\n/sg;
$addon =~ s/\\$/ /s;
print STDERR "$addon\n" if ($cppDebug);
}
$newrawline .= $addon;
}
$dropargs = 0;
}
$lastcpppart = $part;
}
if ($skip) { $skip = 0; }
else {
my $xpart = $part;
if ($part =~ /[\r\n]/) { $xpart = " "; }
$cpptreecur = $cpptreecur->next(HeaderDoc::ParseTree->new());
$cpptreecur->token($xpart);
}
$cppstring .= $part;
}
if ($inMacro && $part ne "define" &&
$part =~ /\w/ && !$inParen) {
$inMacroTail = 1;
}
}
$pos++;
}
if ($incppargs) {
if ($parserState->{inMacro} || $inMacro) {
if ($cppstring !~ s/\\\s*$//s) {
warn "Non-terminated macro.\n";
print STDERR "CPPS: \"$cppstring\"\n";
$incppargs = 0;
}
}
}
if ($incppargs || $inComment) {
print STDERR "Fetching new line ($incppargs, $inComment)\n" if ($cppleaddebug);
$HeaderDoc::CurLine = $inputCounter + $fileoffset;
$line = $inputLines[$inputCounter++];
if ($lang eq "C" && $sublang eq "IDL") {
if ($line =~ /cpp_quote\s*\(\s*\"(.*)\"\s*\)\s*$/) {
print STDERR "CHANGED LINE FROM \"$line\" to " if ($localDebug || $liteDebug);
$line = $1."\n";
$line =~ s/\\\"/"/sg;
print STDERR "\"$line\"\n" if ($localDebug || $liteDebug);
}
}
print STDERR "INCREMENTED INPUTCOUNTER [2]\n" if ($HeaderDoc::inputCounterDebug);
# @parts = split(/(\W)/, $line);
# Perform a minimal tokenization of the new line for C preprocessing purposes.
if ($lang eq "perl" || $lang eq "shell") {
@parts = split(/("|'|\#|\{|\}|\(|\)|\s|;|\\|\W)/, $line);
} elsif ($lang eq "tcl") {
@parts = split(/("|'|\ } else {
@parts = split(/("|'|\/\/|\/\*|\*\/|::|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\W)/, $line);
}
}
print STDERR "LOOPBOTTOM: $incppargs, $inComment\n" if ($hangDebug);
} until (!$incppargs && !$inComment);
# Perform a minimal tokenization of the new line for C preprocessing purposes.
if ($lang eq "perl" || $lang eq "shell") {
@parts = split(/("|'|\#|\{|\}|\(|\)|\s|;|\\|::|\W)/, $newrawline);
} elsif ($lang eq "tcl") {
@parts = split(/("|'|\ } else {
@parts = split(/("|'|\/\/|\/\*|\*\/|::|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\W)/, $newrawline);
}
while (scalar(@cpptrees)) {
my $temptree = pop(@cpptrees);
if ($temptree != $cpptreetop) {
$temptree->dispose();
}
}
$cpptreetop->dispose();
}
if (!$parserState->{inMacro}) {
$parserState->{NEXTTOKENNOCPP} = 0;
}
# Throw away any empty entries caused by Perl seeing two
# adjacent tokens that match the split regexp. We don't
# want them or care about them, and they break things
# rather badly if we don't....
my @stripparts = @parts;
@parts = ();
print STDERR "BEGIN PARTLIST 2:\n" if ($spaceDebug);
foreach my $strippart (@stripparts) {
if (length($strippart)) {
print STDERR "MYPART: \"$strippart\"\n" if ($spaceDebug);
push(@parts, $strippart);
}
}
print STDERR "END PARTLIST 2.\n" if ($spaceDebug);
if (!$disable_cpp && (1 || $HeaderDoc::enable_cpp)) {
if ($cpp_debug_file) {
open(CPP_DEBUG_FILE, ">>$cpp_debug_file");
# print CPP_DEBUG_FILE "DUMPING CPP INFORMATION FOR $fullpath\n";
foreach my $part (@parts) {
print CPP_DEBUG_FILE $part;
}
close(CPP_DEBUG_FILE);
}
}
# This bit of code needs a bit of explanation, I think.
# We need to be able to see the token that follows the one we
# are currently processing. To do this, we actually keep track
# of the current token, and the previous token, but name then
# $nextpart and $part. We do processing on $part, which gets
# assigned the value from $nextpart at the end of the loop.
#
# To avoid losing the last part of the declaration (or needing
# to unroll an extra copy of the entire loop code) we push a
# bogus entry onto the end of the stack, which never gets
# used (other than as a bogus "next part") because we only
# process the value in $part.
#
# To avoid problems, make sure that you don't ever have a regexp
# that would match against this bogus token.
#
my $part = "";
push(@parts, "BOGUSBOGUSBOGUSBOGUSBOGUS");
if ($localDebug || $cppDebug) {foreach my $partlist (@parts) {print STDERR "POSTCPPPARTLIST: \"$partlist\"\n"; }}
foreach my $nextpart (@parts) {
my $hideTokenAndMaybeContents = 0;
my $bshandled = 0;
my $setIsAvailable = 0;
my $trailingHide = 0;
$treeSkip = 0;
my $reMark = "";
print STDERR "INMACROLINE: ".$parserState->{inMacroLine}."\n" if ($localDebug || $parseDebug || $parmDebug);
if ($part) { $leavingRegexp = 0; } # Reset to 0 at the top of the loop.
print STDERR "********************************************************\n" if ($localDebug || $parseDebug);
# $treePopTwo = 0;
# $treePopOnNewLine = 0;
# The current token is now in "part", and the literal next
# token in "nextpart". We can't just work with this as-is,
# though, because you can have multiple spaces, null
# tokens when two of the tokens in the split list occur
# consecutively, etc.
print STDERR "MYPART: \"$part\"\n" if ($localDebug || $spaceDebug);
if ($braceDebug) {
print STDERR "TOBS: \"".peek(\@braceStack)."\"\n";
}
# print STDERR "pushedfuncbrace: ".$parserState->{pushedfuncbrace}."\n";
$forcenobreak = 0;
# Convert CR/LF or LF/CR pair to LF
if ($part eq "\r" && $nextpart eq "\n") { $part = $nextpart ; next; }
if ($part eq "\n" && $nextpart eq "\r") { next; }
# Convert bare CR to LF
if ($nextpart eq "\r") { $nextpart = "\n"; }
if ($localDebug && $nextpart eq "\n") { print STDERR "NEXTPART IS NEWLINE!\n"; }
my $partIsNL = 0;
if ($part eq "\n") {
$partIsNL = 1;
if ($localDebug) { print STDERR "PART IS NEWLINE!\n"; }
}
### if ($nextpart ne "\n" && $nextpart =~ /\s/o) {
### # Replace tabs with spaces.
### $nextpart = " ";
### }
# Replace tabs with spaces.
$part =~ s/\t/ /g;
$nextpart =~ s/\t/ /g;
if ($part ne "\n" && $part =~ /\s/o && $nextpart ne "\n" &&
$nextpart =~ /\s/o) {
# we're a space followed by a space. Join the tokens.
print STDERR "MERGED \"$part\" and \"$nextpart\" into " if ($spaceDebug);
$nextpart = $part.$nextpart;
print STDERR "\"$nextpart\".\n" if ($spaceDebug);
$part = $nextpart;
next;
}
print STDERR "PART IS \"$part\"\n" if ($localDebug || $parserStackDebug || $parseDebug || $liteDebug || $spaceDebug || $tokenDebug);
print STDERR "QUOTED: ".$parserState->isQuoted($lang, $sublang)."\n" if ($localDebug || $parserStackDebug || $parseDebug || $liteDebug || $spaceDebug);
print STDERR "CURLINE IS \"$curline\"\n" if ($localDebug || $hangDebug || $liteDebug);
# print STDERR "RETURNTYPE IS \"$parserState->{returntype}\"\n" if ($localDebug || $hangDebug || $liteDebug);
print STDERR "INOP: ".$parserState->{inOperator}."\n" if ($operatorDebug);
if (!length($nextpart)) {
print STDERR "SKIP NP\n" if ($localDebug);
next;
}
if (!length($part)) {
print STDERR "SKIP PART\n" if ($localDebug);
$part = $nextpart;
next;
}
if ($occPushParserStateOnWordTokenAfterNext > 1) {
if ($part =~ /\w/) {
$occPushParserStateOnWordTokenAfterNext--;
print STDERR "occPushParserStateOnWordTokenAfterNext -> $occPushParserStateOnWordTokenAfterNext (--)\n" if ($localDebug || $parseDebug);
print STDERR "OCCParse Case 1\n" if ($liteDebug);
}
} elsif ($occPushParserStateOnWordTokenAfterNext) {
# if ($part !~ /(\s|<)/)
print STDERR "OCCParse Case 2\n" if ($liteDebug);
if (($part =~ /(\-|\+|\w|\@)/ || ($part eq "/*" && $nextpart eq "!")) && !$parserState->{inComment} && !$parserState->{inInlineComment}) {
# die("PART: $part NP: $nextpart\n");
print STDERR "OCCParse Case 2a\n" if ($liteDebug);
print STDERR "Last tree node set to $treeCur [1]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
print STDERR "parserState pushed onto stack[occPushParserStateOnWordTokenAfterNext]\n" if ($parserStackDebug);
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 0;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
$parserState->{noInsert} = $setNoInsert;
$setNoInsert = 0;
$pushParserStateAtBrace = 0;
$occPushParserStateOnWordTokenAfterNext = 0;
}
}
# If we get here, we aren't skipping a null or whitespace token.
# Let's print a bunch of noise if debugging is enabled.
# if ($part eq "\n" && $nextpart ne "BOGUSBOGUSBOGUSBOGUSBOGUS") {
# $fileoffset++;
# }
if ($part eq "\n" && $incrementoffsetatnewline) {
$incrementoffsetatnewline--;
$fileoffset++;
}
if ($treeDebug > 1) {
print STDERR "TREE DUMP\n";
$treeTop->dbprint();
print STDERR "\nEND TREE DUMP\n";
}
print STDERR "IN LOOP LANG: $lang INITIAL SUBLANG: $sublang\n" if ($localDebug || $parseDebug);
if ($parseDebug) {
print STDERR "PART: $part, type: $parserState->{typestring}, inComment: $parserState->{inComment}, inInlineComment: $parserState->{inInlineComment}, inChar: $parserState->{inChar}.\n" if ($localDebug);
print STDERR "PART: inBrackets: $parserState->{inBrackets}\n" if ($localDebug);
print STDERR "PART: onlyComments: $parserState->{onlyComments}, inClass: $parserState->{inClass}\n";
print STDERR "PART: cbsodname: $parserState->{cbsodname}\n";
print STDERR "PART: classIsObjC: $parserState->{classIsObjC}, PPSAT: $pushParserStateAfterToken, PPSAWordT: $pushParserStateAfterWordToken, PPSABrace: $pushParserStateAtBrace, occPPSOnWordTokenAfterNext: $occPushParserStateOnWordTokenAfterNext\n";
print STDERR "PART: bracecount: " . scalar(@braceStack) . " (init was $parserState->{initbsCount}).\n";
print STDERR "PART: inString: $parserState->{inString}, callbackNamePending: $parserState->{callbackNamePending}, namePending: $parserState->{namePending}, lastsymbol: $parserState->{lastsymbol}, lasttoken: $lasttoken, lastchar: $lastchar, SOL: $parserState->{startOfDec}\n" if ($localDebug);
print STDERR "PART: sodclass: $parserState->{sodclass} sodname: $parserState->{sodname}\n";
print STDERR "PART: sodtype: $parserState->{sodtype}\n";
print STDERR "PART: simpleTypedef: $parserState->{simpleTypedef}\n";
print STDERR "PART: posstypes: $parserState->{posstypes}\n";
print STDERR "PART: seenBraces: $parserState->{seenBraces}\n";
print STDERR "SEENIF: ".$parserState->{seenIf}." INIF: ".$parserState->{INIF}."\n";
} elsif ($parserStateInsertDebug) {
print STDERR "PART: seenBraces: $parserState->{seenBraces}\n";
}
if ($parseDebug || $regexpDebug) {
print STDERR "PART: inRegexp: $inRegexp inRegexpCharClass: $inRegexpCharClass\n";
print STDERR "PART: inRegexpTrailer: $inRegexpTrailer inRegexpFirstPart: $inRegexpFirstPart\n";
print STDERR "PART: leavingRegexp: $leavingRegexp regexpNoInterpolate: $regexpNoInterpolate\n";
print STDERR "PART: inTCLRegExpCommand: ".$parserState->{inTCLRegExpCommand}." afterNL: ".$parserState->{afterNL}."\n";
}
if ($parseDebug) {
print STDERR "PART: seenTilde: $parserState->{seenTilde}\n";
print STDERR "PART: CBN: $parserState->{callbackName}\n";
print STDERR "PART: regexpStack is:";
foreach my $token (@regexpStack) { print STDERR " $token"; }
print STDERR "\n";
print STDERR "PART: npplStack: ".scalar(@{$parserState->{pplStack}})." nparsedParamList: ".scalar(@{$parserState->{parsedParamList}})." nfreezeStack: ".scalar(@{$parserState->{freezeStack}})." frozen: $parserState->{stackFrozen}\n";
print STDERR "PART: inMacro: $parserState->{inMacro} treePopOnNewLine: $treePopOnNewLine\n";
print STDERR "PART: occmethod: $parserState->{occmethod} occmethodname: $parserState->{occmethodname}\n";
print STDERR "PART: returntype is $parserState->{returntype}\n";
print STDERR "length(declaration) = " . length($declaration) ."; length(curline) = " . length($curline) . "\n";
print STDERR "REQUIREDREGEXP IS \"$requiredregexp\"\n";
print STDERR "DEC: $declaration\n$curline\n";
} elsif ($tsDebug || $treeDebug) {
print STDERR "BPPART: $part\n";
}
if ($parseDebug || $parmDebug) {
print STDERR "PARSED PARAM IS NOW: $parsedParam\n";
}
if ($parserStackDebug) {
print STDERR "parserState: STACK CONTAINS ".scalar(@parserStack)." STATES\n";
print STDERR "parserState is $parserState\n";
}
# The ignore function returns either null, an empty string,
# or a string that gives the text equivalent of an availability
# macro. If the token is non-null and the length is non-zero,
# it's an availability macro, so blow it in as if the comment
# contained an @availability tag.
#
my $tempavail = ignore($part, $ignoreref, $perheaderignoreref);
if ($disable_cpp || $parserState->{inString} ||
$parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar} || $inRegexp) {
if ($tempavail == 2 || $tempavail == 3) {
print STDERR "Forcing ignore state to zero. TOKEN: $part TA: $tempavail INSTRING: $parserState->{inString}\n" if ($parseDebug || $regexpDebug);
$tempavail = 0;
}
} elsif ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) {
print STDERR "Forcing ignore state to zero in macro name. TOKEN: $part TA: $tempavail INSTRING: $parserState->{inString}\n" if ($parseDebug || $regexpDebug);
if ($tempavail) {
$parserState->{ignoreAvailabilityMacros} = 1;
$tempavail = 0;
}
}
if ($parserState->{ignoreAvailabilityMacros}) { $tempavail = 0; }
printf("PART: $part TEMPAVAIL: $tempavail\n") if ($localDebug || $gccAttributeDebug);
if ($tempavail && ($tempavail ne "1") && ($tempavail ne "2") && ($tempavail ne "3")) {
$parserState->{availability} = $tempavail;
$setIsAvailable = 1;
# print STDERR "SET IS AVAILABLE[1] FOR PART $part\n";
} elsif ($tempavail eq "2" || $tempavail eq "3") {
# Reusing the GCC attribute handling code because that does exactly what we need.
print STDERR "Attribute-like Availabilitymacro\n" if ($liteDebug);
print STDERR "Function-like availability macro detected. Collecting.\n" if ($localDebug || $gccAttributeDebug);
$parserState->{attributeState} = 1;
# Add __attribute__ as the next token.
my $hidden = 0;
if ($tempavail eq "3") {
$hidden = 3;
}
$treeCur = $treeCur->addSibling($part, $hidden);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
$treeCur->isAvailabilityMacro(1);
# print STDERR "SET IS AVAILABLE[2] FOR PART $part\n";
# print STDERR "PUSHED $treeCur onto tree stack (__OSX_AVAIL...).\n";
push(@treeStack, $treeCur);
my @tempAvailabilityNodesArray = ();
if ($parserState->{availabilityNodesArray}) {
@tempAvailabilityNodesArray = @{$parserState->{availabilityNodesArray}};
}
push(@tempAvailabilityNodesArray, $treeCur);
# print STDERR "ADDED $treeCur\n";
# $treeCur->dbprint();
$parserState->{availabilityNodesArray} = \@tempAvailabilityNodesArray;
# Nest all contents one level lower.
$treeCur = $treeCur->addChild("", 0);
$part = $nextpart;
next;
}
print "IC: $parserState->{inClass} TOK: $part\n" if ($parseDebug || $classDebug);
my $externCDebug = 0;
my $iskw = isKeyword($part, $keywordhashref, $case_sensitive);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) {
# Handle the GCC "__attribute__" extension outside the context of
# the parser because it isn't part of the language and massively
# breaks the syntax.
# Same for asm
if (($iskw == 8) && !$parserState->{attributeState} &&
!$parserState->{parsedParamParse} &&
!$parserState->{inBrackets} &&
!$parserState->{inTemplate} &&
!$parserState->{inChar} &&
!$parserState->{inString} &&
!$parserState->{inComment} &&
!$parserState->{inInlineComment} &&
!$parserState->{inImplements} &&
!$parserState->{inExtends} &&
!$parserState->{inClassConformingToProtocol} &&
!$parserState->{inRuby} &&
!$parserState->{seenBraces} &&
!$parserState->{classNameFound} &&
!$parserState->{inMacro} &&
!$parserState->{inMacroLine} &&
!$parserState->{preEqualsSymbol}) {
print STDERR "Attribute CASE 1\n" if ($liteDebug);
$parserState->{isStatic} = 1;
} elsif (($lang eq "C" || $lang eq "Csource") && ($iskw == 2 || $iskw == 5 || $iskw == 6)) {
print STDERR "Attribute CASE 2\n" if ($liteDebug);
print STDERR "GCC attribute/asm detected. Collecting.\n" if ($localDebug || $gccAttributeDebug);
$parserState->{attributeState} = 1;
# Add __attribute__ as the next token.
$treeCur = $treeCur->addSibling($part, 0);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
push(@treeStack, $treeCur);
# Nest all contents one level lower.
$treeCur = $treeCur->addChild("", 0);
$part = $nextpart;
next;
} elsif (($lang eq "C" || $lang eq "Csource") && ($iskw == 7)) {
print STDERR "Attribute CASE 3 (Extern C)\n" if ($liteDebug);
$parserState->rollbackSet();
print STDERR "EXTERN C -> 1\n" if ($externCDebug);
$parserState->{externC} = 1;
$parserState->{preExternCcurline} = $curline;
$parserState->{preExternCdeclaration} = $declaration;
# $parserState->{preExternCsodname} = $parserState->{sodname};
# $parserState->{preExternCsodclass} = $parserState->{sodclass};
# $parserState->{preExternCsodtype} = $parserState->{sodtype};
# $parserState->{preExternCreturntype} = $parserState->{returntype};
} elsif ($parserState->{attributeState} == 1) {
print STDERR "Attribute CASE 4\n" if ($liteDebug);
if ($part eq "(") {
print STDERR "GCC attribute open paren\n" if ($localDebug || $gccAttributeDebug);
$parserState->{attributeState} = -1;
}
$treeCur = $treeCur->addSibling($part, 0);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
$part = $nextpart;
next;
} elsif ($parserState->{attributeState} < 0) {
print STDERR "Attribute CASE 5\n" if ($liteDebug);
if ($part eq "(") {
print STDERR "Attribute OPAREN\n" if ($liteDebug);
$parserState->{attributeState}--;
print STDERR "GCC attribute open paren, count=".(0-$parserState->{attributeState})."\n" if ($localDebug || $gccAttributeDebug);
} elsif ($part eq ")") {
print STDERR "Attribute CPAREN\n" if ($liteDebug);
$parserState->{attributeState}++;
print STDERR "GCC attribute close paren, count=".(0-$parserState->{attributeState})."\n" if ($localDebug || $gccAttributeDebug);
}
$treeCur = $treeCur->addSibling($part, 0);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
if (!$parserState->{attributeState}) {
print STDERR "GCC attribute: done collecting.\n" if ($localDebug || $gccAttributeDebug);
# Get back to where we started.
$treeCur = pop(@treeStack);
# print STDERR "GOT TC: $treeCur\n";
}
$part = $nextpart;
next;
} elsif ($parserState->{externC} == 1) {
print STDERR "Attribute CASE 6\n" if ($liteDebug);
if ($part =~ /"/) {
print STDERR "EXTERN C -> 2\n" if ($externCDebug);
$parserState->{externC} = 2;
} elsif ($part !~ /\s/) {
print STDERR "EXTERN C -> 0[1]\n" if ($externCDebug);
$parserState->{externC} = 0;
}
} elsif ($parserState->{externC} == 2) {
print STDERR "Attribute CASE 7\n" if ($liteDebug);
if ($part =~ /C/) {
print STDERR "EXTERN C -> 3\n" if ($externCDebug);
$parserState->{externC} = 3;
} elsif ($part !~ /\s/) {
print STDERR "EXTERN C -> 0[2]\n" if ($externCDebug);
$parserState->{externC} = 0;
}
} elsif ($parserState->{externC} == 3) {
print STDERR "Attribute CASE 8\n" if ($liteDebug);
if ($part =~ /"/) {
print STDERR "EXTERN C -> 0[Success]\n" if ($externCDebug);
$parserState->{externC} = 0;
$parserState->{onlyComments} = 1;
$parserState->{rollbackPending} = 1;
# $curline = $parserState->{preExternCcurline};
# $declaration = $parserState->{preExternCdeclaration};
# $parserState->{sodname} = $parserState->{preExternCsodname};
# $parserState->{sodclass} = $parserState->{preExternCsodclass};
# $parserState->{sodtype} = $parserState->{preExternCsodtype};
# $parserState->{returntype} = $parserState->{preExternCreturntype};
} elsif ($part !~ /\s/) {
print STDERR "EXTERN C -> 0[3]\n" if ($externCDebug);
$parserState->{externC} = 0;
}
}
}
# Here be the parser. Abandon all hope, ye who enter here.
$treepart = "";
my $tempInIf = 0;
if ((!$parserState->{inComment}) && (!$parserState->{inInlineComment}) && ($part ne $parseTokens{ilc}) && (($part ne $parseTokens{soc}) || $nextpart eq "!")) {
if ($parserState->{inProtocol} == 1) {
print STDERR "INPROTOCOL: 1\n" if ($parseDebug || $classDebug);
if ($part =~ /\w/) {
print STDERR "INPROTOCOL: 1 -> 2\n" if ($parseDebug || $classDebug);
$parserState->{inProtocol} = 2;
}
} elsif ($parserState->{inProtocol} == 2) {
print STDERR "INPROTOCOL: 2\n" if ($parseDebug || $classDebug);
if ($part eq "<") {
print STDERR "INPROTOCOL: 2 -> 3\n" if ($parseDebug || $classDebug);
$parserState->{extendsProtocol} = "";
$parserState->{inProtocol} = 3;
} elsif ($part =~ /\S/) {
# PUSH PARSER STATE
# Don't do this if the next thing is a non-HeaderDoc
# comment, though.
print STDERR "parserState pushed onto stack[PROTOCOL]\n" if ($parserStackDebug);
$parserState->{inProtocol} = -1;
print STDERR "Last tree node set to $treeCur [2]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
$pushParserStateAfterWordToken = 0;
}
} elsif ($parserState->{inProtocol} == 3) {
print STDERR "INPROTOCOL: 3\n" if ($parseDebug || $classDebug);
if ($part eq ">") {
print STDERR "INPROTOCOL: 3 -> 2\n" if ($parseDebug || $classDebug);
$parserState->{inProtocol} = 2;
} else {
$parserState->{extendsProtocol} .= $part;
}
}
if ($parserState->{inClass} == 3) {
print STDERR "INCLASS3\n" if ($parseDebug || $classDebug);
if ($part eq ")") {
$parserState->{inClass} = 1;
print STDERR "inClass -> 1 [1]\n" if ($classDebug);
$parserState->{categoryClass} .= $part;
print STDERR "parserState will be pushed onto stack[cparen3]\n" if ($parserStackDebug);
# print STDERR "Last tree node set to $treeCur [2a]\n" if ($parserStateInsertDebug);
# $parserState->{lastTreeNode} = $treeCur;
# push(@parserStack, $parserState);
# $parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
# $parserState->{inputCounter} = $inputCounter;
# $parserState->{initbsCount} = scalar(@braceStack);
$pushParserStateAfterToken = 1;
} elsif ($part eq ":") {
$parserState->{inClass} = 1;
print STDERR "inClass -> 1 [2]\n" if ($classDebug);
if ($parserState->{classIsObjC}) {
print STDERR "occPushParserStateOnWordTokenAfterNext -> 2\n" if ($localDebug || $parseDebug);
$occPushParserStateOnWordTokenAfterNext = 2;
} else {
$pushParserStateAfterWordToken = 1;
}
# if ($sublang eq "occ") {
# $pushParserStateAtBrace = 2;
# }
} elsif ($part =~ /</ && $parserState->{classIsObjC}) {
print STDERR "pushParserStateAfterWordToken -> 0 (Conforming)\n" if ($localDebug || $parseDebug);
print STDERR "inClassConformingToProtocol -> 1\n" if ($localDebug || $parseDebug);
$pushParserStateAfterWordToken = 0;
$parserState->{inClassConformingToProtocol} = 1;
$occPushParserStateOnWordTokenAfterNext = 0;
} elsif ($part =~ />/ && $parserState->{classIsObjC} && $parserState->{inClassConformingToProtocol}) {
print STDERR "inClassConformingToProtocol -> 0\n" if ($localDebug || $parseDebug);
$pushParserStateAfterToken = 1;
print STDERR "pushParserStateAfterWordToken -> 1 (Conforming)\n" if ($localDebug || $parseDebug);
$parserState->{inClassConformingToProtocol} = 0;
} else {
$parserState->{categoryClass} .= $part;
}
} elsif ($parserState->{inClass} == 2) {
print STDERR "INCLASS2\n" if ($parseDebug || $classDebug);
if ($part eq ")") {
$parserState->{inClass} = 1;
print STDERR "inClass -> 1 [3]\n" if ($classDebug);
print STDERR "Last tree node set to $treeCur [3]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
print STDERR "parserState pushed onto stack[cparen2]\n" if ($parserStackDebug);
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
} elsif ($part eq ":") {
$parserState->{inClass} = 1;
print STDERR "inClass -> 1 [4]\n" if ($classDebug);
if ($parserState->{classIsObjC}) {
print STDERR "occPushParserStateOnWordTokenAfterNext -> 2\n" if ($localDebug || $parseDebug);
$occPushParserStateOnWordTokenAfterNext = 2;
} else {
$pushParserStateAfterWordToken = 2;
}
} elsif ($part =~ /\w/) {
# skip the class name itself.
$parserState->{inClass} = 3;
print STDERR "inClass -> 3 [5]\n" if ($classDebug);
}
} elsif ($parserState->{inClass} == 1) {
print STDERR "INCLASS1\n" if ($parseDebug || $classDebug);
# print STDERR "inclass Part is $part\n";
print STDERR "IK: $part => ".isKeyword($part, $keywordhashref, $case_sensitive)."\n" if ($parseDebug || $classDebug);;
if ($part eq "::") {
print STDERR "INCLASS DOUBLE-COLON\n" if ($classDebug);
$parserState->{classNameFound} = 0;
if ($parserState->{perlClassName}) {
$parserState->{perlClassName} .= $parserState->{sodname}."::";
} else {
$parserState->{perlClassName} = $parserState->{sodname}."::";
}
$parserState->{startOfDec} = 1; # Skip the :: token; the name is after it.
print STDERR "PCN: ".$parserState->{perlClassName}."\n" if ($classDebug);
} elsif ($part eq "." && !($parserState->{forceClassDone} || $parserState->{inExtends} ||
$parserState->{inImplements} ||
$parserState->{inClassConformingToProtocol} ||
$parserState->{forceClassSuper})) {
print STDERR "INCLASS DOT\n" if ($parseDebug || $classDebug);
$parserState->{classNameConcat} = 1;
# print STDERR "XSUPER: $parserState->{forceClassSuper}\n";
} elsif ($part eq ":") {
print STDERR "INCLASS COLON\n" if ($parseDebug || $classDebug);
if (!$parserState->{forceClassName}) {
$parserState->{forceClassName} = $parserState->{sodname};
$parserState->{forceClassSuper} = "";
}
# print STDERR "XSUPER: $parserState->{forceClassSuper}\n";
} elsif (isKeyword($part, $keywordhashref, $case_sensitive) == 3) {
if (!$parserState->{forceClassName}) {
$parserState->{forceClassName} = $parserState->{sodname};
}
$parserState->{inExtends} = 1;
$parserState->{inImplements} = 0;
if ($parserState->{extendsClass}) {
$parserState->{extendsClass} .= " ";
} else {
$parserState->{extendsClass} = "";
}
} elsif (isKeyword($part, $keywordhashref, $case_sensitive) == 4) {
if (!$parserState->{forceClassName}) {
$parserState->{forceClassName} = $parserState->{sodname};
}
$parserState->{inImplements} = 1;
$parserState->{inExtends} = 0;
if ($parserState->{implementsClass}) {
$parserState->{implementsClass} .= " ";
} else {
$parserState->{implementsClass} = "";
}
} elsif ($parserState->isLeftBrace($part, $lang, \%parseTokens, $case_sensitive, scalar(@braceStack)) || $part eq ";") {
# $part eq "{"
print STDERR "INCLASS BRCSEMI\n" if ($parseDebug || $classDebug);
$parserState->{forceClassDone} = 1;
if ($parserState->{classIsObjC} && $part eq "{") {
$parserState->{ISFORWARDDECLARATION} = 0;
print STDERR "Last tree node set to $treeCur [4]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
print STDERR "parserState pushed onto stack[OCC-BRCSEMI]\n" if ($parserStackDebug);
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 0;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack) + 1; # NOTE: add one here because it will change in the SWITCH to follow.
$parserState->{noInsert} = $setNoInsert;
$setNoInsert = 0;
$pushParserStateAtBrace = 0;
$occPushParserStateOnWordTokenAfterNext = 0;
$pushParserStateAfterToken = 1;
} elsif ($part eq ";") {
if (!defined($parserState->{ISFORWARDDECLARATION})) {
print STDERR "FORWARD DECLARATION DETECTED\n" if ($parseDebug || $localDebug || $liteDebug);
# print STDERR "PREVIOUS FD STATE: ".$parserState->{ISFORWARDDECLARATION}."\n";
$parserState->{ISFORWARDDECLARATION} = 1;
}
$pushParserStateAtBrace = 0;
$occPushParserStateOnWordTokenAfterNext = 0;
$pushParserStateAfterToken = 0;
}
} elsif ($parserState->{forceClassName} && !$parserState->{forceClassDone} && !$parserState->{inImplements} && !$parserState->{inExtends}) {
print STDERR "INCLASS ADD\n" if ($parseDebug || $classDebug);
if ($part =~ /[\n\r]/) {
$parserState->{forceClassSuper} .= " ";
} else {
$parserState->{forceClassSuper} .= $part;
}
# print STDERR "SUPER IS $parserState->{forceClassSuper}\n";
} elsif ($part =~ /</ && $parserState->{classIsObjC} && $occPushParserStateOnWordTokenAfterNext) {
print STDERR "INCLASS <\n" if ($parseDebug || $classDebug);
print STDERR "pushParserStateAfterWordToken -> 0 (Conforming)\n" if ($localDebug || $parseDebug);
print STDERR "inClassConformingToProtocol -> 1\n" if ($localDebug || $parseDebug);
$pushParserStateAfterWordToken = 0;
$parserState->{inClassConformingToProtocol} = 1;
$occPushParserStateOnWordTokenAfterNext = 0;
} elsif ($part =~ />/ && $parserState->{classIsObjC} && $parserState->{inClassConformingToProtocol}) {
print STDERR "INCLASS >\n" if ($parseDebug || $classDebug);
print STDERR "inClassConformingToProtocol -> 0\n" if ($localDebug || $parseDebug);
$pushParserStateAfterToken = 1;
print STDERR "pushParserStateAfterWordToken -> 1 (Conforming)\n" if ($localDebug || $parseDebug);
$parserState->{inClassConformingToProtocol} = 0;
} elsif ($occPushParserStateOnWordTokenAfterNext && $part =~ /\w/) {
print STDERR "INCLASS OCCSUPER\n" if ($parseDebug || $classDebug);
$parserState->{occSuper} = $part;
# $occPushParserStateOnWordTokenAfterNext = 0;
# $pushParserStateAfterToken = 1;
} elsif ($parserState->{inExtends}) {
print STDERR "INCLASS INEXTENDS (PART: \"$part\")\n" if ($parseDebug || $classDebug);
$parserState->{extendsClass} .= $part;
} elsif ($parserState->{inImplements}) {
print STDERR "INCLASS INIMPLEMENTS (PART: \"$part\")\n" if ($parseDebug || $classDebug);
$parserState->{implementsClass} .= $part;
} elsif (!$parserState->{classIsObjC}) {
print STDERR "INCLASS NOTOBJC (OTHER)\n" if ($parseDebug || $classDebug);
if (!(scalar(@braceStack) - $parserState->{initbsCount})) {
if ($part =~ /[*(^]/) {
print STDERR "INCLASS DROP\n" if ($parseDebug || $classDebug);
$parserState->{inClass} = 0; # We're an instance. Either a variable or a function.
print STDERR "inClass -> 0 [6]\n" if ($classDebug);
$parserState->{sodtype} = $parserState->{preclasssodtype} . $parserState->{sodtype};
} elsif ($part =~ /\w/) {
print STDERR "INCLASS GOT WORD TOKEN\n" if ($parseDebug || $classDebug);
if ($parserState->{classNameFound} && !$parserState->{forceClassName} && !$parserState->{classNameConcat}) {
print STDERR "INCLASS NOT A CLASS. IT IS A VARIABLE OR TYPEDEF.\n" if ($parseDebug || $classDebug);
$parserState->{inClass} = 0;
} elsif ($parserState->{classNameConcat}) {
# Once per dot.
# $parserState->dbprint();
$parserState->{classNameConcat} = 0;
$parserState->{forceClassName} = $parserState->{sodtype}.".".$part;
} else {
print STDERR "INCLASS WORD TOKEN IS CLASS NAME\n" if ($parseDebug || $classDebug);
$parserState->{classNameFound} = 1;
}
}
}
# } else {
# print STDERR "BUG\n";
}
};
if ($parserState->{inClassConformingToProtocol} == 1) {
$parserState->{inClassConformingToProtocol} = 2;
} elsif ($parserState->{inClassConformingToProtocol}) {
$parserState->{conformsToList} .= $part;
}
if ($macroDebug) {
print STDERR "MNT: ".$parserState->{macroNoTrunc}."\n";
}
# if (($part eq $parseTokens{ilc} || $part eq $parseTokens{ilc_b}) && ($lang ne "perl" || $lasttoken ne "\$")) {
# print STDERR "should be ILC?\n";
# } else {
# print STDERR "NO CHANEC: PART \"$part\" ILC \"$parseTokens{ilc}\" ILC_B: \"$parseTokens{ilc_b}\" LANG: \"$lang\" LASTTOKEN: \"$lasttoken\"\n";
# }
$parserState->dbprint() if ($regexpDebug == 2);
print STDERR "LASTNSPART: $lastnspart\n" if ($regexpDebug == 2);
print STDERR "\n
(($inRegexp &&\n
(length($regexpcharpattern) &&\n
$part =~ /^($regexpcharpattern)$/ &&\n
(!$inRegexpCharClass) &&\n
(!scalar(\@regexpStack) || $part eq peekmatch(\\\@regexpStack, $lang, $fullpath, $inputCounter))\n
)\n
) || (\n
(!$inRegexp) &&\n
($parserState->{lastsymbol} =~ /$regexpAllowedAfter/ ||\n
$parserState->{inTCLRegExpCommand} ||\n
($parserState->{lastsymbol} eq \"\" && $lastnspart eq \"(\" && peek(\\\@braceStack) eq \"(\")\n
) && $part =~ /\// && !$parserState->{inTemplate} &&\n
length($regexpfirstcharpattern) &&\n
(!($inRegexp || $inRegexpTrailer ||\n
$parserState->{inString} || $parserState->{inComment} ||\n
$parserState->{inInlineComment} || $parserState->{inChar})) &&\n
(!$parserState->isRubyOpenQuote($part) || $parserState->isRubyCloseQuote($part)) &&\n
(length($regexpfirstcharpattern) &&\n
$part =~ /^($regexpfirstcharpattern)$/ &&\n
(!$inRegexpCharClass) &&\n
(!scalar(\@regexpStack) || $part eq peekmatch(\\\@regexpStack, $lang, $fullpath, $inputCounter))\n
)\n
\n" if ($regexpDebug == 2);
if ($HeaderDoc::parseIfElse && (!$parserState->{inMacro} && !$parserState->{inMacroLine} && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}))) {
if (!(scalar(@braceStack) - $parserState->{initbsCount})) {
if ($part eq "if" || $part eq "else") {
print STDERR "INIF OUTSIDE CHANGE -> 1 FOR PART \"$part\" IN $parserState\n" if ($continueDebug);
if ($part eq "if") {
$parserState->{seenIf} = 1; # Hint for code that uses results.
$parserState->{INIF} = 1;
} else {
# print STDERR "SETTING IFCONTENTS TO ".$parserState->{functionContents}."\n";
$parserState->{ifContents} = $parserState->{functionContents};
$parserState->{functionContents} = "";
$parserState->{seenElse} = 1; # Hint for code that uses results.
$parserState->{INIF} = 1;
}
print STDERR "CONTINUE -> 1 [INIF]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
$continue = 1;
# $pushParserStateAtBrace = 1;
} elsif ($part eq ";") {
# Not in "if" after the close curly brace.
print STDERR "INIF OUTSIDE CHANGE -> 0 FOR PART \"$part\" IN $parserState\n" if ($continueDebug);
$parserState->{INIF} = 0;
} elsif ($part eq "{") {
# Not in "if" after the close curly brace.
print STDERR "INIF OUTSIDE CHANGE -> 0 FOR PART \"$part\" IN $parserState\n" if ($continueDebug);
$tempInIf = $parserState->{INIF};
print STDERR "TEMPINIF: $tempInIf\n" if ($continueDebug);
$parserState->{INIF} = 0;
} elsif ($part =~ /\S/ && $part ne "(" && $parserState->{INIF}) {
$parserState->{INIF}++;
$parserState->{seenBraces} = 1;
print STDERR "seenBraces -> 1 [1]\n" if ($parseDebug || $braceDebug);
} else {
print STDERR "INIF OUTSIDE NC (".$parserState->{INIF}.") FOR PART \"$part\" IN $parserState\n" if ($continueDebug);
}
# print STDERR "DEBUG $pushParserStateAfterToken $pushParserStateAfterWordToken $pushParserStateAtBrace $occPushParserStateOnWordTokenAfterNext\n";
} else {
print STDERR "INIF INSIDE NC (".$parserState->{INIF}.") FOR PART \"$part\" IN $parserState\n" if ($continueDebug);
# print STDERR "DEBUG $pushParserStateAfterToken $pushParserStateAfterWordToken $pushParserStateAtBrace $occPushParserStateOnWordTokenAfterNext\n";
}
}
if ($part ne ":" && $parserState->{inBitfield}) {
print STDERR "BITFIELD CONFIRMED.\n" if ($parmDebug || $parseDebug || $localDebug || $bitfieldDebug);
$parserState->{startOfDec} = 0;
delete $parserState->{inBitfield};
}
}
# print STDERR "VARCHECK: $parseTokens{varname} :: $part eq $parseTokens{varname} :: $inRegexp :: $inRegexpTrailer :: $parserState->{inString} :: $parserState->{inComment} :: $parserState->{inInlineComment} :: $parserState->{inChar} :: $parserState->{sodclass}\n";
# The phrase "foo.bar" is a valid name in these languages.
# This code handles that....
if ( ( ($lang eq "C" && $sublang eq "IDL") ||
$lang eq "javascript" ||
$lang eq "java") &&
($parserState->{callbackNamePending} || $parserState->{namePending} || $parserState->{startOfDec} == 2) &&
$part eq "." &&
!$parserState->{classNameConcat} &&
!$parserState->{variableNameConcat}) {
print STDERR "IDL/JS/Java CONCAT -> 1\n" if ($liteDebug);
$parserState->{variableNameConcat} = 2;
};
# The phrase "foo::bar" is a valid name in these languages.
# This code handles that....
if ( ($lang eq "perl") &&
($parserState->{callbackNamePending} || $parserState->{namePending} || $parserState->{startOfDec} == 2) &&
$part eq "::" &&
!$parserState->{classNameConcat} &&
!$parserState->{variableNameConcat} &&
($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces})) {
print STDERR "Perl CONCAT -> 1\n" if ($liteDebug);
$parserState->{variableNameConcat} = 2;
};
if ($part =~ /[\n\r]/) {
# 2 until first non-space token.
$parserState->{afterNL} = 2;
if ($lang eq "tcl") {
if ($parserState->{inTCLRegExpCommand}) {
$parserState->{inTCLRegExpCommand} = 0;
}
}
} elsif ($parserState->{afterNL} == 1) {
# 0 after first non-space token.
$parserState->{afterNL} = 0;
} elsif ($parserState->{afterNL} == 2 && $part =~ /\S/) {
# 1 during first non-space token.
$parserState->{afterNL} = 1;
}
SWITCH: {
# Blank declaration handlers (mostly for misuse of
# OSMetaClassDeclareReservedUsed and similar)
(($lang eq "applescript") && !$argparse && ($part eq "|") &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar})) && do {
print STDERR "APPLESCRIPT CONCAT: CASE AS_00a\n" if ($liteDebug);
if ($asConcat) {
$part = $asConcat . $part;
$asConcat = "";
# Fall through.
} else {
$asConcat = $part;
$part = "";
last SWITCH;
}
};
(($lang eq "applescript") && !$argparse && ($asConcat) &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar})) && do {
print STDERR "APPLESCRIPT CONCAT: CASE AS_00b\n" if ($liteDebug);
$asConcat .= $part;
$part = "";
last SWITCH;
};
(($lang eq "applescript") && !$argparse && ($part =~ /^(of|in)$/) &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar})) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00A\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT OF/IN: SET TO $part\n" if ($asDebug);
$parserState->{inOfIn} = 1;
$parserState->{OfIn} = $part;
last SWITCH;
};
(($lang eq "applescript") &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar}) &&
$parserState->{inOfIn} && ($part =~ /\w/)) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00B\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT OF/IN: ADDING $part\n" if ($asDebug);
$parserState->{OfIn} .= " ".$part;
$parserState->{inOfIn} = 0;
last SWITCH;
};
(($lang eq "applescript") &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar}) &&
!$argparse && $labelregexp && ($part =~ /$labelregexp/) && ($parserState->{startOfDec} != 1)) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00C\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT LABEL: SET TO $part SOD=".$parserState->{startOfDec}."\n" if ($asDebug);
$parserState->{inLabel} = 1;
$parserState->{ASlabel} = $part;
last SWITCH;
};
(($lang eq "applescript") &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar}) &&
$labelregexp && $parserState->{inLabel} && ($part =~ /\w/)) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00D\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT LABEL: ADDING $part\n" if ($asDebug);
$parserState->{ASlabel} .= " ".$part;
$parserState->{inLabel} = 0;
last SWITCH;
};
(($lang eq "applescript") &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar}) &&
($part eq "given")) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00E\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT GIVEN ($part)\n" if ($asDebug);
$parserState->{inGiven} = 1;
$parserState->{inLabel} = 0;
last SWITCH;
};
(($lang eq "applescript") && $parserState->{inGiven} &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} ||
$parserState->{inChar}) &&
($part !~ /[\r\n]/)) && do {
print STDERR "APPLESCRIPT OF/IN: CASE AS_00F\n" if ($liteDebug);
print STDERR "IN APPLESCRIPT GIVEN\n" if ($asDebug);
if ($part eq ",") {
print STDERR "IN APPLESCRIPT GIVEN COMMA\n" if ($asDebug);
print STDERR "PUSHING \"$parsedParam\" onto parsed parameters list (comma)\n" if ($parseDebug || $asDebug);
if (length($parsedParam)) { push(@{$parserState->{parsedParamList}}, $parsedParam); }
$parsedParam = "";
} else {
print STDERR "IN APPLESCRIPT GIVEN TOKEN: $part\n" if ($asDebug);
$parsedParam .= $part;
}
last SWITCH;
};
# (($lang eq "applescript") && $argparse && ($part eq ":")) && do {
# print STDERR "APPLESCRIPT OF/IN: CASE AS_00G\n" if ($liteDebug);
# print STDERR "IN APPLESCRIPT GIVEN: IGNORING COLON\n" if ($asDebug);
# $treepart = "";
# last SWITCH;
# };
(($iskw == 9) && ($parserState->{afterSemi} || $parserState->{firstpastnl})) && do {
print STDERR "ISKEYWORD == 9: CASE KW_0A\n" if ($liteDebug);
$parserState->{inCase}++;
print STDERR "inCase -> ".$parserState->{inCase}."\n" if ($parseDebug || $localDebug || $braceDebug);
};
(($iskw == 10) && ($parserState->{afterSemi} == 2)) && do { # && ($parserState->{afterSemi} >= 2)) && do {
print STDERR "ISKEYWORD == 10: CASE KW_0B\n" if ($liteDebug);
# print "AFTERSEMI: ".$parserState->{afterSemi}."\n" if ($parseDebug || $localDebug || $braceDebug);
$parserState->{inCase}--;
print STDERR "inCase -> ".$parserState->{inCase}."\n" if ($parseDebug || $localDebug || $braceDebug);
};
(($part eq ";") && ($parserState->{startOfDec} == 1) && !$parserState->{inMacro} && !$parserState->{inMacroLine} && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) && do {
print STDERR "LEADING SEMICOLON: CASE 01\n" if ($liteDebug);
print STDERR "Dropping empty declaration\n" if ($localDebug || $parseDebug);
$part = "";
last SWITCH;
};
(length($TCLregexpcommand) && ($part =~ /^$TCLregexpcommand$/) &&
($parserState->{lastsymbol} eq ";" || $parserState->{afterNL} ||
$lasttoken eq "["
) &&
(!($inRegexp || $inRegexpTrailer || $parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}))) && do {
print STDERR "TCL REGEXP: CASE 01A\n" if ($liteDebug);
$parserState->{inTCLRegExpCommand} = 1;
# print STDERR "LS: $parserState->{lastsymbol} ANL: $parserState->{afterNL} LT: $lasttoken\n";
# Fall through
};
(($lang eq "perl" || $lang eq "shell") && $part eq "<<" && !$parserState->{attributeState} &&
!$parserState->{parsedParamParse} &&
!$parserState->{inBrackets} &&
!$parserState->{inTemplate} &&
!$parserState->{inChar} &&
!$parserState->{inString} &&
!$parserState->{inComment} &&
!$parserState->{inInlineComment} &&
!$parserState->{inImplements} &&
!$parserState->{inExtends} &&
!$parserState->{inClassConformingToProtocol} &&
!$parserState->{inRuby} &&
!$parserState->{seenBraces} &&
!$parserState->{classNameFound} &&
!$parserState->{inMacro} &&
!$parserState->{inMacroLine}) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01B\n" if ($liteDebug);
$parserState->{inString} = 13;
$parserState->{endOfString} = "";
# print STDERR "Aha\n";
$treeNest = 1;
last SWITCH;
};
(($lang eq "perl" || $lang eq "shell") && ($parserState->{inString} == 13) && ($parserState->{endOfString} eq "") && $part =~ /\S/) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01C\n" if ($liteDebug);
$parserState->{endOfString} = $part;
last SWITCH;
};
(($lang eq "perl" || $lang eq "shell") && ($parserState->{inString} == 13) && ($part =~ /[\n\r]/)) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01D\n" if ($liteDebug);
$parserState->{firstpastnl} = 1;
last SWITCH;
};
(($lang eq "perl" || $lang eq "shell") && ($parserState->{inString} == 13) && ($part eq $parserState->{endOfString}) && $parserState->{firstpastnl}) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01E\n" if ($liteDebug);
my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [3]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
last SWITCH;
};
(($lang eq "perl" || $lang eq "shell") && ($parserState->{inString} == 13) && $part =~ /\S/ && $parserState->{firstpastnl}) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01F\n" if ($liteDebug);
$parserState->{firstpastnl} = 0;
last SWITCH;
};
(($lang eq "perl" || $lang eq "shell") && ($parserState->{inString} == 13)) && do {
print STDERR "PERL OR SHELL MULTI-LINE STRING: CASE 01G\n" if ($liteDebug);
last SWITCH;
};
# Macro handlers
(($parserState->{inMacro} == 1) && ($part eq "define")) && do {
print STDERR "INMACRO/DEFINE: CASE 02\n" if ($liteDebug);
# define may be a multi-line macro
print STDERR "INMACRO AND DEFINE\n" if ($parseDebug || $localDebug);
$parserState->{inMacro} = 3;
print STDERR "inMacro -> 3\n" if ($macroDebug || $cppDebug);
$parserState->{sodname} = "";
my $pound = $treeCur->token();
if ($pound eq $parseTokens{sopreproc}) {
$treeNest = 2;
if ($treeDebug) { print STDERR "TS TREENEST -> 2 [1]\n"; }
$treePopOnNewLine = 2;
$pound .= $part;
$treeCur->token($pound);
}
last SWITCH;
};
# (($parserState->{inMacro} == 1 && $macrore_pound ne "" && $part =~ /(if|ifdef|ifndef|endif|else|undef|elif|error|warning|pragma|import|include)/ && ($part ne $parseTokens{definename})) || ($parserState->{inMacro} == 0 && $macrore_nopound ne "" && $part =~ /$macrore_nopound/))
# (($parserState->{inMacro} == 1 && $part =~ /(if|ifdef|ifndef|endif|else|undef|elif|error|warning|pragma|import|include)/ )) && do
(!$parserState->{inComment} && (($parserState->{inMacro} == 1 && $macrore_pound ne "" && $part =~ /^$macrore_pound$/ && ($part ne $parseTokens{definename})) || ($parserState->{inMacro} == 0 && $macrore_nopound ne "" && $part =~ /^$macrore_nopound$/))) && do {
print STDERR "MACRORE-v: \"$macrore_pound\"\n" if ($macroDebug);
print STDERR "MACRORE-r: \"(if|ifdef|ifndef|endif|else|undef|elif|error|warning|pragma|import|include)\"\n" if ($macroDebug);
print STDERR "MACRORE-n: \"$macrore_nopound\"\n" if ($macroDebug);
print STDERR "INMACRO/IF: CASE 03\n" if ($liteDebug);
print STDERR "INMACRO AND IF/IFDEF/IFNDEF/ENDIF/ELSE/PRAGMA/IMPORT/INCLUDE\n" if ($parseDebug || $localDebug);
# these are all single-line macros
$parserState->{inMacro} = 4;
print STDERR "inMacro -> 4\n" if ($macroDebug || $cppDebug);
$parserState->{sodname} = "";
my $pound = $treeCur->token();
if ($pound eq $parseTokens{sopreproc}) {
$treeNest = 2;
if ($treeDebug) { print STDERR "TS TREENEST -> 2 [2]\n"; }
$treePopOnNewLine = 1;
$pound .= $part;
$treeCur->token($pound);
if ($part eq "endif") {
# the rest of the line is not part of the macro
# NOTE: Do not change treeCur in the
# next line.
$treeCur->addChild("\n", 0);
$treeNest = 0;
if ($treeDebug) { print STDERR "TS TREENEST -> 0 [3]\n"; }
$treePopOnNewLine = 0;
$treeSkip = 1;
}
}
last SWITCH;
};
(($parserState->{inMacroLine} == 1) && ($part =~ /(if|ifdef|ifndef|endif|else|undef|elif|error|warning|pragma|import|include|define)/o)) && do {
print STDERR "INMACROLINE/IF: CASE 04\n" if ($liteDebug);
print STDERR "INMACROLINE AND IF/IFDEF/IFNDEF/ENDIF/ELSE/PRAGMA/IMPORT/INCLUDE\n" if ($parseDebug || $localDebug);
my $pound = $treeCur->token();
if ($pound eq $parseTokens{sopreproc}) {
$pound .= $part;
$treeCur->token($pound);
if ($part =~ /define/o) {
$treeNest = 2;
if ($treeDebug) { print STDERR "TS TREENEST -> 2 [4]\n"; }
$treePopOnNewLine = 2;
} elsif ($part eq "endif") {
# the rest of the line is not part of the macro
# NOTE: Do not change treeCur in the
# next line.
$treeCur->addChild("\n", 0);
$treeNest = 0;
if ($treeDebug) { print STDERR "TS TREENEST -> 0 [5]\n"; }
$treePopOnNewLine = 0;
$treeSkip = 1;
} else {
$treeNest = 2;
if ($treeDebug) { print STDERR "TS TREENEST -> 2 [6]\n"; }
$treePopOnNewLine = 1;
}
}
last SWITCH;
};
($parserState->{inMacro} == 1 && ($part ne $parseTokens{soc}) && ($part ne $parseTokens{eoc}) && $part =~ /\s/) && do {
print STDERR "INMACRO SPACE: CASE 04A\n" if ($liteDebug);
$treepart = $part; $part = "";
last SWITCH;
};
($parserState->{inMacro} == 1 && ($part ne $parseTokens{soc}) && ($part ne $parseTokens{eoc})) && do {
print STDERR "INMACRO PPTOKEN: CASE 05\n" if ($liteDebug);
print STDERR "INMACRO IS 1, CHANGING TO 2 (NO PROCESSING)\n" if ($parseDebug || $localDebug);
# error case.
$parserState->{inMacro} = 2;
print STDERR "inMacro -> 2\n" if ($macroDebug || $cppDebug);
last SWITCH;
};
($parserState->{inMacro} > 1 && $part ne "//" && $part !~ /[\n\r]/ && ($part ne $parseTokens{soc}) && ($part ne $parseTokens{eoc})) && do {
print STDERR "INMACRO OTHERTOKEN: CASE 06\n" if ($liteDebug);
if ($part eq "(") {
if ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) {
$parserState->{cppMacroHasArgs} = 1;
}
}
print STDERR "INMACRO > 1, PART NE //" if ($parseDebug || $localDebug);
if ($cppDebug || $parseDebug) {
print STDERR "\nISQUOTED: ".$parserState->isQuoted($lang, $sublang)."\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
}
if ($part eq "\\") {
print STDERR "BS ADD\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
$parserState->addBackslash();
$bshandled = 1;
print STDERR "ISQUOTED NOW: ".$parserState->isQuoted($lang, $sublang)."\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
} elsif ($part !~ /[ \t]/) {
print STDERR "BS RESET\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
$parserState->resetBackslash();
$bshandled = 1;
print STDERR "ISQUOTED NOW: ".$parserState->isQuoted($lang, $sublang)."\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
}
print STDERR "PART: $part\n" if ($macroDebug);
if ($parserState->{seenMacroPart}) {
print STDERR "MACRO: SMP&TI\n" if ($macroDebug);
if (!(scalar(@braceStack) - $parserState->{initbsCount})) {
print STDERR "MACRO: NOSTACK\n" if ($macroDebug);
if ($part =~ /\s/o && $parserState->{macroNoTrunc} == 1) {
print STDERR "MACRO: ENDOFNAME\n" if ($macroDebug);
$parserState->{macroNoTrunc} = 0;
$treeCur->{HIDEMACROLASTTOKEN} = 1;
} elsif ($part =~ /[\{\(]/o) {
print STDERR "MACRO: BRACE\n" if ($macroDebug);
if (!$parserState->{macroNoTrunc}) {
print STDERR "END OF MACRO\n" if ($macroDebug);
if ($HeaderDoc::truncate_inline) {
$HeaderDoc::hidetokens = 3;
} else {
$treeCur->{HIDEMACROLASTTOKEN} = 2;
}
}
} else {
print STDERR "MACRO: OTHERTOKEN\n" if ($macroDebug);
$parserState->{macroNoTrunc} = 2;
}
}
}
if ($part =~ /[\{\(]/o) {
push(@braceStack, $part);
push(@parsedParamParseStack, $parserState->{parsedParamParse});
print STDERR "PUSHED $part ONTO BRACESTACK [1]\n" if ($macroDebug || $braceDebug);
} elsif ($part =~ /[\}\)]/o) {
if ($part ne peekmatch(\@braceStack, $lang, $fullpath, $inputCounter)) {
if ($parserState->{macroNoTrunc} == 1) {
warn("$fullpath:$inputCounter: warning: Initial braces in macro name do not match.\nWe may have a problem.\n");
}
}
my $temp = pop(@braceStack);
$parserState->{parsedParamParse} = pop(@parsedParamParseStack);
print STDERR "POPPED $temp FROM BRACESTACK [1]\n" if ($macroDebug || $braceDebug);
}
if ($part =~ /\S/o) {
$parserState->{seenMacroPart} = 1;
$parserState->{lastsymbol} = $part;
if (($parserState->{sodname} eq "") && ($parserState->{inMacro} == 3)) {
print STDERR "DEFINE NAME IS $part\n" if ($macroDebug);
$parserState->{sodname} = $part;
}
}
$lastchar = $part;
last SWITCH;
};
(length($parseTokens{varname}) && $part eq $parseTokens{varname} && !($inRegexp || $inRegexpTrailer || $parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && !$parserState->{sodclass}) && do {
print "VARNAME: CASE 06A\n" if ($liteDebug);
$parserState->{sodclass} = "variable";
$parserState->{onlyComments} = 0;
if ($lang eq "applescript" || $lang eq "tcl") {
print STDERR "declarationEndsAtNewLine -> 1 [AS]\n" if ($parseDebug || $asDebug);
$parserState->{declarationEndsAtNewLine} = 1;
}
print STDERR "sodclass -> variable (explicit[1])\n" if ($sodDebug);
print STDERR "DETECTED VARIABLE KEYWORD\n" if ($localDebug || $parseDebug);
};
(length($parseTokens{constname}) && $part eq $parseTokens{constname} && !($inRegexp || $inRegexpTrailer || $parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && (!(scalar(@braceStack) - $parserState->{initbsCount}))) && do {
print STDERR "CONST: CASE 06B\n" if ($liteDebug);
$parserState->{constKeywordFound} = 1;
print STDERR "DETECTED CONSTANT KEYWORD\n" if ($localDebug || $parseDebug);
};
(length($regexppattern) && $part ne $parseTokens{soc} && $part ne $parseTokens{eoc} && $part ne $parseTokens{ilc} && $part ne $parseTokens{ilc_b} && $parserState->{lastsymbol} ne "\$" && $part =~ /^($regexppattern)$/ && !($inRegexp || $inRegexpTrailer || $parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) && do {
print STDERR "REGEXP PATTERN: CASE 07\n" if ($liteDebug);
my $match = $1;
print STDERR "REGEXP WITH PREFIX\n" if ($regexpDebug);
$regexpNoInterpolate = 0;
if ($match =~ /^($singleregexppattern)$/) {
print STDERR "SINGLE REGEXP\n" if ($regexpDebug);
print STDERR "INREGEXP -> 2 [1]\n" if ($regexpDebug);
$inRegexp = 2;
} else {
print STDERR "INREGEXP -> 4 [2]\n" if ($regexpDebug);
$inRegexp = 4;
print STDERR "DOUBLE REGEXP\n" if ($regexpDebug);
if ($part eq "tr") { $regexpNoInterpolate = 1; }
}
$reMark = "RE_PREFIX";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
$inRegexpFirstPart = 2;
last SWITCH;
}; (($inRegexp &&
(length($regexpcharpattern) &&
$part =~ /^($regexpcharpattern)$/ &&
(!$inRegexpCharClass) &&
(!scalar(@regexpStack) || $part eq peekmatch(\@regexpStack, $lang, $fullpath, $inputCounter))
)
) || (
(!$inRegexp) && $part ne $parseTokens{soc} && $part ne $parseTokens{eoc} && $part ne $parseTokens{ilc} && $part ne $parseTokens{ilc_b} &&
($parserState->{lastsymbol} =~ /$regexpAllowedAfter/ ||
($parseTokens{regexpAllowedAtStartOfLine} && $parserState->{afterNL}) ||
$parserState->{inTCLRegExpCommand} ||
($parserState->{lastsymbol} eq "" && $lastnspart eq "(" && peek(\@braceStack) eq "(")
) &&
length($regexpfirstcharpattern) &&
$part =~ /$regexpfirstcharpattern/ && !$parserState->{inTemplate} &&
(!($inRegexp || $inRegexpTrailer ||
$parserState->{inString} || $parserState->{inComment} ||
$parserState->{inInlineComment} || $parserState->{inChar})) &&
(!$parserState->isRubyOpenQuote($part) || $parserState->isRubyCloseQuote($part)) &&
(!$inRegexpCharClass) &&
(!scalar(@regexpStack) || $part eq peekmatch(\@regexpStack, $lang, $fullpath, $inputCounter))
)
) && do {
print STDERR "REGEXP CHARACTER: CASE 08\n" if ($liteDebug);
print STDERR "REGEXP?\n" if ($regexpDebug);
if ($parserState->{inTCLRegExpCommand}) {
$parserState->{inTCLRegExpCommand} = 0;
}
if ($parserState->isQuoted($lang, $sublang) ||
((!$inRegexp) && $lasttoken eq "\$")) {
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
} else {
print STDERR "REGEXP POINT A\n" if ($regexpDebug);
print STDERR "INREGEXP is $inRegexp\n" if ($regexpDebug);
if (!$inRegexp) {
print STDERR "INREGEXP -> 3 [3]\n" if ($regexpDebug);
$inRegexp = 2;
print STDERR "IRFP -> 1\n" if ($regexpDebug);
$inRegexpFirstPart = 1;
$reMark = "RE_START";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
} elsif ($inRegexpFirstPart != 2) {
print STDERR "IRFP -> 0\n" if ($regexpDebug);
$inRegexpFirstPart = 0;
$reMark = "RE_PARTSEP";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
} else {
print STDERR "IRFP -> 1\n" if ($regexpDebug);
$inRegexpFirstPart = 1;
$reMark = "RE_START";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
my $is_a_comment = 0;
if ($part eq "#" &&
((scalar(@regexpStack) != 1) ||
(peekmatch(\@regexpStack, $lang, $fullpath, $inputCounter) ne "#"))) {
if ($nextpart =~ /^\s/o) {
$is_a_comment = 1;
}
}
if (!$is_a_comment) {
my $fall_through = 0;
print STDERR "REGEXP POINT B\n" if ($regexpDebug);
if (!scalar(@regexpStack)) {
print STDERR "PUSHING $part ONTO REGEXPSTACK [1]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $part);
$inRegexp--;
if (!$inRegexp) {
$leavingRegexp = 1;
$reMark = "RE_END";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
print STDERR "INREGEXP -> $inRegexp [4]\n" if ($regexpDebug);
} else {
my $match = peekmatch(\@regexpStack, $lang, $fullpath, $inputCounter);
my $tos = pop(@regexpStack);
print STDERR "popped $tos FROM REGEXPSTACK\n" if ($localDebug || $parseDebug || $regexpDebug);
if (!scalar(@regexpStack) && ($match eq $part)) {
$inRegexp--;
if (!$inRegexp) {
$leavingRegexp = 1;
$reMark = "RE_END";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
print STDERR "INREGEXP -> $inRegexp [5]\n" if ($regexpDebug);
if ($inRegexp == 2 && ($tos eq "/" || $tos eq "|")) {
$inRegexp--;
if (!$inRegexp) {
$leavingRegexp = 1;
$reMark = "RE_END";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
print STDERR "INREGEXP -> $inRegexp [6]\n" if ($regexpDebug);
}
if ($inRegexp) {
print STDERR "PUSHING $tos ONTO REGEXPSTACK [2]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $tos);
}
} elsif (scalar(@regexpStack) == 1) {
print STDERR "PUSHING $tos ONTO REGEXPSTACK [3]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $tos);
if ($tos =~ /['"`|{}]/o || $regexpNoInterpolate) {
# these don't interpolate.
$fall_through = 1;
}
} else {
print STDERR "PUSHING $tos ONTO REGEXPSTACK [4]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $tos);
if ($tos =~ /['"`|{}]/o || $regexpNoInterpolate) {
# these don't interpolate.
$fall_through = 1;
} else {
print STDERR "PUSHING $part ONTO REGEXPSTACK [5]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $part);
}
}
}
if (!$fall_through) {
print STDERR "REGEXP POINT C\n" if ($regexpDebug);
if (!$inRegexp) {
$inRegexpTrailer = 2;
}
last SWITCH;
}
}
}
};
($part eq $parseTokens{sopreproc}) && do {
print STDERR "SOPREPROC: CASE 09\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($parserState->{onlyComments}) {
print STDERR "inMacro -> 1\n" if ($macroDebug || $cppDebug);
$parserState->{inMacro} = 1;
} elsif ($curline =~ /^\s*$/o) {
$parserState->{inMacroLine} = 1;
print STDERR "IML\n" if ($localDebug);
} elsif ($postPossNL) {
print STDERR "PRE-IML \"$curline\"\n" if ($localDebug || $macroDebug);
$treeCur = $treeCur->addSibling("\n", 0);
bless($treeCur, "HeaderDoc::ParseTree");
$parserState->{inMacroLine} = 1;
$postPossNL = 0;
}
}
};
(($part eq $parseTokens{sofunction} || $part eq $parseTokens{soprocedure} || $part eq $parseTokens{soconstructor}) &&
(($lang ne "applescript") || $parserState->appleScriptFunctionLegalHere(\@braceStack)) &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) &&
!(scalar(@braceStack)-$parserState->{initbsCount}) && !$parserState->{seenBraces}) && do {
print STDERR "SOFUNC: CASE 10\n" if ($liteDebug);
if ($part eq $parseTokens{soconstructor}) {
$parserState->{isConstructor} = 1;
}
if ($lang eq "tcl" && scalar(@parserStack)) {
print STDERR "declarationEndsAtNewLine -> 1 (SOPROC/FUNC/CONS)\n" if ($parseDebug);
$parserState->{declarationEndsAtNewLine} = 1;
}
$parserState->{sodclass} = "function";
$parserState->{onlyComments} = 0;
$parserState->{lastsymbol} = $part;
print STDERR "sodclass -> function (explicit[2])\n" if ($sodDebug);
print STDERR "FUNCTION OR PROCEDURE FOUND [1].\n" if ($localDebug);
if (!$pascal && !$ruby && ($lang ne "tcl") && ($lang ne "applescript") && $lang ne "perl") {
$parserState->{kr_c_function} = 1;
}
$parserState->{typestring} = "function";
$parserState->{startOfDec} = 2;
print STDERR "startOfDec -> 2 [1]\n" if ($localDebug);
$parserState->{namePending} = 1;
print STDERR "namePending -> 1 [1]\n" if ($parseDebug);
if ($parseTokens{functionisbrace} && $parserState->{sodclass} eq "function" &&
!$parserState->{pushedfuncbrace}) {
$parserState->{pushedfuncbrace} = 1;
}
if ($parseTokens{parmswithcurlybraces}) {
$parserState->{pendingBracedParameters} = 1;
}
if ($parseTokens{functionisapiowner}) {
$pushParserStateAtBrace = 1;
}
last SWITCH;
};
($part =~ /\~/o && ($lang eq "C" || $lang eq "Csource") && $sublang eq "cpp" && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) && do {
print STDERR "C++ DESTRUCTOR: CASE 11\n" if ($liteDebug);
print STDERR "TILDE\n" if ($localDebug);
$parserState->{seenTilde} = 2;
$lastchar = $part;
$parserState->{onlyComments} = 0;
last SWITCH;
};
($part =~ /[-+]/o && ($lang eq "C" || $lang eq "Csource") && $parserState->{onlyComments}) && do {
print STDERR "OBJC METHOD: CASE 12\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
print STDERR "OCCMETHOD\n" if ($localDebug);
$parserState->{occmethod} = 1;
$parserState->{occmethodtype} = $part;
$parserState->{occmethodreturntype} = "";
$lastchar = $part;
$parserState->{onlyComments} = 0;
print STDERR "[a]onlyComments -> 0\n" if ($macroDebug);
if (!$parserState->{seenBraces}) { if (!$parserState->{hollow}) {
print STDERR "SETHOLLOW -> 1\n" if ($parserStackDebug);
$sethollow = 1;
}
$treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [7]\n"; }
$parserState->{treePopTwo} = 1;
}
}
last SWITCH;
};
($part =~ /[\n\r]/o && ($parserState->{inString} != 13) &&
(!($parseTokens{classisbrace} && $parserState->{sodclass} eq "class" && (!$parserState->{inRubyClass}))) &&
(!($parseTokens{functionisbrace} && $parserState->{pushedfuncbrace} == 1)) &&
($parserState->isQuoted($lang, $sublang) || (!$parserState->{newlineIsSemi}))) && do {
my $precursor = $parserState->clearLeftBracePrecursor();
if ($precursor) {
push(@braceStack, $precursor);
print STDERR "Pushing $precursor onto the brace stack [clearLeftBracePrecursor]\n" if ($HeaderDoc::AppleScriptDebug || $braceDebug || $parseDebug);
}
if ($lang eq "shell") {
if ($part eq ";;") {
$parserState->{afterSemi} = 2;
} elsif (!$parserState->{afterSemi}) {
$parserState->{afterSemi} = 1;
}
}
print STDERR "NEWLINE: CASE 13\n" if ($liteDebug);
my $prev_inInlineComment = $parserState->{inInlineComment};
$parserState->{inInlineComment} = 0;
print STDERR "inInlineComment -> 0\n" if ($ilcDebug);
if ($ruby) {
$parserState->{followingrubyrbrace} = 0;
}
if ($parserState->{pushedfuncbrace}) {
print STDERR "OOH. We are in a function now.\n" if ($parseDebug);
$parserState->{inOfIn} = 0;
$parserState->{inLabel} = 0;
$parserState->{inGiven} = 0;
$treeCur = $treeCur->addSibling("", 0);
bless($treeCur, "HeaderDoc::ParseTree");
$parserState->{startOfDec} = 0;
}
$treepart = $part;
if ($inRegexp) {
warn "$fullpath:$inputCounter: warning: multi-line regular expression\n";
print STDERR "DECTODATE: $declaration".$line."\n";
}
print STDERR "NLCR\n" if ($tsDebug || $treeDebug || $localDebug);
if ($lastchar !~ /[\,\;\{\(\)\}]/o && $nextpart !~ /[\{\}\(\)]/o) {
if ($lastchar ne "*/" && $nextpart ne "/*") {
if (!$parserState->{inMacro} && !$parserState->{inMacroLine} && !$treePopOnNewLine) {
print STDERR "NL->SPC\n" if ($localDebug);
$part = " ";
print STDERR "LC: $lastchar\n" if ($localDebug);
print STDERR "NP: $nextpart\n" if ($localDebug);
$postPossNL = 2;
} elsif ($treePopOnNewLine && $prev_inInlineComment) {
if ($parserState->{inMacroLine}) {
print STDERR "skipped pushing CPP directive $parsedParam into parsedParamList [0]\n" if ($parmDebug || $cppDebug || $localDebug);
$parserState->{inMacroLine} = 0;
$parsedParam = "";
} else {
print STDERR "Keeping parsed parameter $parsedParam because we're leaving a single-line comment.\n" if ($parmDebug || $cppDebug || $localDebug);
}
} else {
if ($parserState->{inMacroLine}) {
print STDERR "skipped pushing CPP directive $parsedParam into parsedParamList [1]\n" if ($parmDebug || $cppDebug || $localDebug);
} else {
print STDERR "cleared parsed parameter $parsedParam"." [1]\n" if ($parmDebug || $cppDebug || $localDebug);
}
$parserState->{inMacroLine} = 0;
$parsedParam = "";
}
} elsif ($parserState->{inMacroLine}) {
$parserState->{inMacroLine} = 0;
print STDERR "skipped pushing CPP directive $parsedParam into parsedParamList [2]\n" if ($parmDebug || $cppDebug || $localDebug);
$parsedParam = "";
}
} elsif ($parserState->{inMacroLine}) {
$parserState->{inMacroLine} = 0;
print STDERR "skipped pushing CPP directive $parsedParam into parsedParamList [3]\n" if ($parmDebug || $cppDebug || $localDebug);
$parsedParam = "";
}
if (($lang eq "shell" && $parserState->{sodclass} ne "function") ||
($ruby && ($parserState->{sodclass} ne "class" && $parserState->{sodclass} ne "function") && !scalar(@parserStack))) {
print STDERR "SC: ".$parserState->{sodclass}."\n" if ($localDebug || $parseDebug || $rubyDebug);
if (!($parserState->{inString} || $parserState->{inChar})) {
if (!$parserState->isQuoted($lang, $sublang)) {
print STDERR "LS: ".$parserState->{lastsymbol}."\n" if ($localDebug || $parseDebug);
print STDERR "CONTINUE -> 0 [1aa]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
$continue = 0;
}
}
}
print STDERR "TPONL: $treePopOnNewLine\n" if ($liteDebug);
if ($treePopOnNewLine < 0) {
$treePopOnNewLine = 0 - $treePopOnNewLine;
$treeCur = $treeCur->addSibling($treepart, 0);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
bless($treeCur, "HeaderDoc::ParseTree");
$treeSkip = 1;
$treeCur = pop(@treeStack);
if (!$treeCur) {
$treeCur = $treeTop;
warn "$fullpath:$inputCounter: warning: Attempted to pop off top of tree";
}
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [1]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($treePopOnNewLine == 1 || ($treePopOnNewLine && !$parserState->isQuoted($lang, $sublang))) {
$treeCur = $treeCur->addSibling($treepart, 0);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
bless($treeCur, "HeaderDoc::ParseTree");
$treeSkip = 1;
$treeCur = pop(@treeStack);
if (!$treeCur) {
$treeCur = $treeTop;
warn "$fullpath:$inputCounter: warning: Attempted to pop off top of tree";
}
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->addSibling("", 0); print STDERR "TSPOP [1a]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
$treePopOnNewLine = 0;
$HeaderDoc::hidetokens = 0;
} else {
print STDERR "Not popping from tree. Probably quoted.\n" if ($localDebug || $parseDebug);
}
next SWITCH;
};
($part eq $parseTokens{sotemplate} && (($lang eq "perl" && $parserState->{lastsymbol} eq "=" && !$inRegexp) || ($lang ne "perl" && ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) && (!$parserState->{inMacroLine}) && (!$parserState->{inMacro}) && (!$parserState->{INIF}))) && ($parserState->{inOperator} != 1)) && do {
print STDERR "C++ TEMPLATE: CASE 14\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($HeaderDoc::hideIDLAttributes && $lang eq "C" && $sublang eq "IDL") { $hideTokenAndMaybeContents = 3; }
print STDERR "inTemplate -> ".($parserState->{inTemplate}+1)."\n" if ($localDebug);
print STDERR "SBS: " . scalar(@braceStack) . ".\n" if ($localDebug);
$parserState->{inTemplate}++;
if (!(scalar(@braceStack) - $parserState->{initbsCount})) {
$parserState->{preTemplateSymbol} = $parserState->{lastsymbol};
}
$parserState->{lastsymbol} = "";
$lastchar = $part;
$parserState->{onlyComments} = 0;
push(@parsedParamParseStack, $parserState->{parsedParamParse});
push(@braceStack, $part); pbs(@braceStack);
print STDERR "PUSHED $part ONTO BRACESTACK [2]\n" if ($macroDebug || $braceDebug);
print STDERR "LINE: $line\n" if ($regexpDebug && $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if (!$parserState->{seenBraces}) {
if (!$parserState->{hollow}) { $sethollow = 1; } }
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [8]\n"; }
}
print STDERR "[b]onlyComments -> 0\n" if ($macroDebug);
}
last SWITCH;
};
($part eq $parseTokens{eotemplate} && (($lang eq "perl" && $parserState->{inTemplate} && !$inRegexp) || ($lang ne "perl" && ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) && (!$parserState->{inMacroLine}) && (!$parserState->{inMacro}) && (!$parserState->{INIF}))) && ($parserState->{inOperator} != 1)) && do {
print STDERR "C++ TEMPLATE END: CASE 15\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && (!(scalar(@braceStack)-$parserState->{initbsCount}) || $parserState->{inTemplate})) {
if ($parserState->{inTemplate}) {
print STDERR "parserState->{inTemplate} -> ".($parserState->{inTemplate}-1)."\n" if ($localDebug);
$parserState->{inTemplate}--;
$parserState->{lastsymbol} = "";
$lastchar = $part;
$curline .= " ";
$parserState->{onlyComments} = 0;
print STDERR "[c]onlyComments -> 0\n" if ($macroDebug);
}
my $top = pop(@braceStack);
$parserState->{parsedParamParse} = pop(@parsedParamParseStack);
print STDERR "POPPED $top FROM BRACESTACK [2]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
if (!$parserState->{seenBraces}) { $treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
$treeCur = $treeCur->lastSibling();
if (!$parserState->{seenBraces}) { $treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
print STDERR "TSPOP [2]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($top ne $parseTokens{sotemplate}) {
if ($lang eq "perl") {
push(@braceStack, $top);
print STDERR "PUSHED $top ONTO BRACESTACK [2A]\n" if ($macroDebug || $braceDebug);
} else {
warn("$fullpath:$inputCounter: warning: Template (angle) brackets do not match.\nWe may have a problem.\n");
}
}
}
last SWITCH;
};
($ruby && ($part eq "<") && ($parserState->{sodclass} eq "class")) && do {
print STDERR "RUBY LEFT ANGLE BRACE: CASE 15A\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && (!(scalar(@braceStack)-$parserState->{initbsCount}))) {
$parserState->{waitingForExceptions} = 1;
}
};
($part eq ":" && (!$parseTokens{assignmentwithcolon})) && do {
print STDERR "Access control colon: CASE 16\n" if ($liteDebug);
print STDERR "TS IS \"$parserState->{typestring}\"\n" if ($localDebug || $parseDebug);
if ($inRegexp && $inRegexpCharClass && ($inRegexpCharClass != 2) && ($inRegexpCharClass < 4) && $lasttoken eq "[") {
print STDERR "In regexp nested character class (e.g. [:space:]).\n" if ($regexpDebug || $parseDebug);
$inRegexpCharClass = 4;
} elsif ($inRegexp && ($inRegexpCharClass >= 4)) {
print STDERR "In regexp nested character class (e.g. [:space:]).\n" if ($regexpDebug || $parseDebug);
$inRegexpCharClass = 6;
} elsif (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($pascal && (!(scalar(@braceStack)-$parserState->{initbsCount}))) {
print STDERR "Clearing SOD (pascal variable)\n" if ($sodDebug || $localDebug);
$parserState->{startOfDec} = 1;
print STDERR "startOfDec -> 1 [2]\n" if ($localDebug);
print STDERR "SODCLASS: \"$parserState->{sodclass}\"\n" if ($sodDebug || $localDebug);
if ($parserState->{sodclass} ne "function") {
print STDERR "sodclass -> function (implicit)[3]\n" if ($sodDebug);
$parserState->{sodclass} = "variable";
}
$parserState->{nameList} = $parserState->{sodtype}." ".$parserState->{sodname};
print STDERR "NL: $parserState->{nameList}\n" if ($sodDebug || $localDebug);
$parserState->{sodname} = "";
$parserState->{sodtype} = "";
$parserState->{waitingForTypeInformation} = 2;
print STDERR "CLEARING CURLINE ($curline)\n" if ($sodDebug || $localDebug);
$curline = "";
}
if (length($accessregexp) && ($lastnspart =~ /$accessregexp/)) {
print STDERR "PERMANENT ACS CHANGE from $HeaderDoc::AccessControlState to $1\n" if ($localDebug);
$parserState->{sodname} = "";
$parserState->{typestring} = "";
print STDERR "RESET HOLLOW at $part\n" if ($parserStackDebug);
if ($parserState->{hollow}) {
my $node = $parserState->{hollow};
$node->{BLOCKOFFSET} = undef;
$node->{INPUTCOUNTER} = undef;
}
$parserState->{hollow} = undef;
$parserState->{returntype} = ""; $curline = "";
$parserState->{onlyComments} = 1;
print STDERR "SET onlyComments to 1\n" if ($parserStateInsertDebug || $parseDebug);
print STDERR "hollowskip -> 1 (ACS)\n" if ($parserStateInsertDebug);
$hollowskip = 1;
$HeaderDoc::AccessControlState = $1;
$lastACS = $1;
last SWITCH;
} elsif ($parseTokens{structname} && $parserState->{typestring} eq $parseTokens{structname}) {
print STDERR "STRUCT CASE\n" if ($parmDebug || $localDebug);
if (!(scalar(@braceStack) - $parserState->{initbsCount})) {
print STDERR "STRUCT CASE OUTER\n" if ($parmDebug || $localDebug);
if (!$parserState->{structClassName}) {
print STDERR "STRUCT NAME BLANK\n" if ($parmDebug || $localDebug);
$parserState->{structClassName} = $parserState->{lastsymbol};
$parserState->{bracePending} = 2;
}
}
} elsif ($parserState->{inBitfield}) {
print STDERR "NOT IN BITFIELD (::)\n" if ($parmDebug || $parseDebug || $localDebug || $bitfieldDebug);
delete $parserState->{inBitfield};
} elsif ($parserState->{sodclass} ne "class" &&
!$parserState->{occmethod} && !$parserState->{inMacro} &&
!$parserState->{inEnum} && !$parserState->{inClass} &&
!$parserState->{seenBraces} && ($lang eq "C" || $lang eq "Csource") && ($sublang ne "MIG")) {
print STDERR "SC: $parserState->{sodclass} ST: $parserState->{sodtype}\n" if ($localDebug || $parseDebug);
print STDERR "IN BITFIELD?\n" if ($parmDebug || $parseDebug || $localDebug || $bitfieldDebug);
$parserState->{inBitfield} = 1;
}
}
};
(length($accessregexp) && ($part =~ /$accessregexp/)) && do {
print STDERR "Access regexp: CASE 17\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($part =~ /^\@(.*)$/) {
print STDERR "PERMANENT ACS CHANGE from $HeaderDoc::AccessControlState to $1\n" if ($localDebug);
$parserState->{sodname} = "";
$parserState->{typestring} = "";
print STDERR "RESET HOLLOW at $part\n" if ($parserStackDebug);
$parserState->{hollow} = undef;
$parserState->{onlyComments} = 1;
$hollowskip = 1;
print STDERR "hollowskip -> 1 (\@ACS)\n" if ($parserStateInsertDebug);
$HeaderDoc::AccessControlState = $1;
$lastACS = $1;
last SWITCH;
} else {
print STDERR "TEMPORARY ACS CHANGE from $HeaderDoc::AccessControlState to $1\n" if ($localDebug);
$parserState->{sodname} = "";
$lastACS = $HeaderDoc::AccessControlState;
$HeaderDoc::AccessControlState = $1;
}
} else {
next SWITCH;
}
};
(length($requiredregexp) && $part =~ /$requiredregexp/) && do {
print STDERR "REQUIRED REGEXP: CASE 17A\n" if ($liteDebug);
print STDERR "REQUIRED REGEXP MATCH: \"$part\"\n" if ($localDebug || $parseDebug);
$hollowskip = 1;
print STDERR "hollowskip -> 1 (requiredregexp)\n" if ($parserStateInsertDebug);
$HeaderDoc::OptionalOrRequired = $part;
$parserState->{optionalOrRequired} = $part;
last SWITCH;
};
($part eq ":" && (!$parseTokens{assignmentwithcolon})) && do {
print STDERR "Copy constructor: CASE 18\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($parserState->{occmethod}) {
$parserState->{name} = $parserState->{lastsymbol};
if ($parserState->{occparmlabelfound}) {
$parserState->{occmethodname} .= "$parserState->{lastsymbol}:";
if ($occMethodNameDebug) {
print STDERR "OCC method name now ".$parserState->{occmethodname}." (lastsymbol was \"".$parserState->{lastsymbol}."\").\n";
}
$parserState->{occparmlabelfound} = -1; } else {
if ($occMethodNameDebug) {
print STDERR "OCC method name missing.\n";
print STDERR "OCC method name still ".$parserState->{occmethodname}." (lastsymbol was \"".$parserState->{lastsymbol}."\").\n";
}
$parserState->{occparmlabelfound} = -2; }
if ($parserState->{occmethod} == 1) {
$parserState->{occmethod} = 2;
if (!$prespace) { $prespaceadjust = 4; }
$parserState->{onlyComments} = 0;
print STDERR "[d]onlyComments -> 0\n" if ($macroDebug);
}
} else {
if (($lang eq "C" || $lang eq "Csource") && $sublang eq "cpp") {
if (!(scalar(@braceStack)-$parserState->{initbsCount}) && $parserState->{sodclass} eq "function") {
$inPrivateParamTypes = 1;
$declaration .= "$curline";
$publicDeclaration = $declaration;
$declaration = "";
} else {
next SWITCH;
}
if (!$parserState->{stackFrozen}) {
if (scalar(@{$parserState->{parsedParamList}})) {
foreach my $node (@{$parserState->{parsedParamList}}) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@{$parserState->{pplStack}}, $node)
}
}
@{$parserState->{parsedParamList}} = ();
print STDERR "parsedParamList pushed [1]\n" if ($parmDebug);
}
@{$parserState->{freezeStack}} = @{$parserState->{pplStack}};
$parserState->{frozensodname} = $parserState->{sodname};
$parserState->{stackFrozen} = 1;
}
} else {
next SWITCH;
}
}
if (($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) && !$parserState->{occmethod}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [9]\n"; }
$parserState->{treePopTwo} = 1;
}
last SWITCH;
} else {
print STDERR "NOPE\n" if ($liteDebug);
next SWITCH;
}
};
($part =~ /\s/o && $part !~ /[\n\r]/o) && do {
print STDERR "Whitespace: CASE 19\n" if ($liteDebug);
if ($parserState->{parsedParamParse} == 5) {
print STDERR "PUSHED \"$parsedParam\" onto parsedParamList\n" if ($parmDebug);
if (length($parsedParam)) { push(@{$parserState->{parsedParamList}}, $parsedParam); }
$parsedParam = "";
}
$lastchar = $part;
last SWITCH;
};
($part =~ /\\/o) && do {
print STDERR "BACKSLASH: CASE 20\n" if ($liteDebug);
$parserState->{lastsymbol} = $part; $lastchar = $part;
$parserState->addBackslash();
};
($part eq "\"" ||
($ruby && ($parserState->isRubyOpenQuote($part) ||
$parserState->isRubyCloseQuote($part)))) && do {
print STDERR "DOUBLE QUOTE: CASE 21\n" if ($liteDebug);
print STDERR "dquo\n" if ($localDebug);
if ((!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $inRegexp)) && ($parserState->isRubyCloseQuote($part) || !$parserState->{inRuby})) {
if ($ruby) {
$parserState->{inRuby} = $parserState->isRubyOpenQuote($part);
}
$parserState->{onlyComments} = 0;
print STDERR "[e]onlyComments -> 0\n" if ($macroDebug);
print STDERR "LASTTOKEN: $lasttoken\nCS: $curstring\n" if ($localDebug);
if (!$parserState->isQuoted($lang, $sublang)) {
if (!$parserState->{inString}) {
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [10]\n"; }
}
} else {
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [3]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
$parserState->{inString} = (1-$parserState->{inString});
print STDERR "INSTRING -> ".$parserState->{inString} ."\n" if ($liteDebug || $parseDebug || $localDebug);
}
}
$lastchar = $part;
$parserState->{lastsymbol} = "";
last SWITCH;
};
($part eq "[") && do {
print STDERR "LEFT BRACKET: CASE 22\n" if ($liteDebug);
my $fall_through = 0;
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($inRegexp && $inRegexpCharClass) {
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
$fall_through = 1;
} elsif (!$parserState->isQuoted($lang, $sublang)) {
if ($inRegexp && $inRegexpFirstPart == 1) {
print STDERR "inRegexpCharClass -> 3\n" if ($regexpDebug);
$inRegexpCharClass = 3;
$reMark = "RE_CCSTART";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
print STDERR "lbracket\n" if ($localDebug);
print STDERR "LBRACKET DEBUG TRACE: SODNAME: ".$parserState->{sodname}." SODTYPE: ".$parserState->{sodtype}." SIMPLETDCONTENTS: ".$parserState->{simpleTDcontents}."\n" if ($localDebug);
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inString})) {
$parserState->{onlyComments} = 0;
print STDERR "[f]onlyComments -> 0\n" if ($macroDebug);
}
push(@parsedParamParseStack, $parserState->{parsedParamParse});
push(@braceStack, $part); pbs(@braceStack);
print STDERR "PUSHED $part ONTO BRACESTACK [3]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [11]\n"; }
}
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$parserState->{inBrackets} += 1;
} else {
print STDERR "FALLING THROUGH (QUOTED)\n" if ($localDebug);
$fall_through = 1;
}
}
if (!$fall_through) {
$lastchar = $part;
if ($parserState->{startOfDec} == 2) {
if (!$parserState->{inTemplate}) {
if (!$parserState->{sodbrackets}) {
$parserState->{sodbrackets} = $part;
} else {
$parserState->{sodbrackets} .= $part;
}
print STDERR "sodbrackets set to ".$parserState->{sodbrackets}."\n" if ($sodDebug);
} else {
print STDERR "Not adjusting startOfDec or sodname because in template.\n" if ($localDebug || $sodDebug);
}
}
last SWITCH;
}
};
($part eq "]") && do {
print STDERR "CLOSE BRACKET: CASE 23\n" if ($liteDebug);
if ($inRegexp && ($inRegexpCharClass == 5)) {
print STDERR "Leaving nested character class.\n" if ($localDebug || $parseDebug || $regexpDebug);
$inRegexpCharClass = 1;
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
} elsif ($inRegexp && ($inRegexpCharClass == 2)) {
print STDERR "First in character class. Treating as literal.\n" if ($localDebug || $parseDebug || $regexpDebug);
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
} elsif ($inRegexp && ($parserState->isQuoted($lang, $sublang))) {
my $place = "regular expression";
if ($inRegexpCharClass) { $place = "character class"; }
print STDERR "Quoted ] in $place. Treating as literal.\n" if ($localDebug || $parseDebug || $regexpDebug);
$lasttoken = $part;
$parserState->{lastsymbol} = $part;
} else {
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
print STDERR "rbracket\n" if ($localDebug || $regexpDebug);
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inString})) {
$parserState->{onlyComments} = 0;
print STDERR "[g]onlyComments -> 0\n" if ($macroDebug);
}
my $top = pop(@braceStack);
$parserState->{parsedParamParse} = pop(@parsedParamParseStack);
print STDERR "POPPED $top FROM BRACESTACK [3]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [4]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($top ne "[") {
warn("$fullpath:$inputCounter: warning: Square brackets do not match.\nWe may have a problem.\n");
warn("Declaration to date: $declaration$curline\n");
}
pbs(@braceStack);
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$parserState->{inBrackets} -= 1;
}
print "RECC: $inRegexpCharClass\n" if ($regexpDebug);
if ($inRegexpCharClass) {
if ($inRegexpCharClass != 4) {
print STDERR "Leaving character class.\n" if ($localDebug || $parseDebug || $regexpDebug);
$inRegexpCharClass = 0;
$reMark = "RE_CCEND";
if ($reMarkDebug) { print STDERR "REMARK: $reMark\n"; }
}
}
$lastchar = $part;
if ($parserState->{startOfDec} == 2) {
if (!$parserState->{inTemplate}) {
if (!$parserState->{sodbrackets}) {
$parserState->{sodbrackets} = $part;
} else {
$parserState->{sodbrackets} .= $part;
}
print STDERR "sodbrackets set to ".$parserState->{sodbrackets}."\n" if ($sodDebug);
} else {
print STDERR "Not adjusting startOfDec or sodname because in template.\n" if ($localDebug || $sodDebug);
}
}
last SWITCH;
}
};
($part eq "'" && $lang ne "applescript") && do {
print STDERR "SINGLE QUOTE: CASE 24\n" if ($liteDebug);
print STDERR "squo\n" if ($localDebug);
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inString} || $inRegexp)) {
if (!$parserState->isQuoted($lang, $sublang)) {
$parserState->{onlyComments} = 0;
print STDERR "[h]onlyComments -> 0\n" if ($macroDebug);
if (!$parserState->{inChar}) {
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [12]\n"; }
}
} else {
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [5]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
$parserState->{inChar} = !$parserState->{inChar};
}
if ($lastchar =~ /\=$/o) {
$curline .= " ";
}
}
$parserState->{lastsymbol} = "";
$lastchar = $part;
last SWITCH;
};
(($part eq $parseTokens{ilc} || $part eq $parseTokens{ilc_b}) && ($lang ne "perl" || $lasttoken ne "\$")) && do {
print STDERR "SINGLE LINE COMMENT: CASE 25\n" if ($liteDebug);
print STDERR "ILC\n" if ($localDebug || $ilcDebug);
if (!($parserState->{inComment} || $parserState->{inChar} || $parserState->{inString} || $inRegexp ||
$parserState->{inInlineComment})) {
$parserState->{inInlineComment} = 4;
print STDERR "inInlineComment -> 1\n" if ($ilcDebug);
$curline = spacefix($curline, $part, $lastchar, $parseTokens{soc}, $parseTokens{eoc}, $parseTokens{ilc}, $parseTokens{ilc_b});
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [13]\n"; }
if (!$treePopOnNewLine) {
$treePopOnNewLine = 1;
} else {
$treePopOnNewLine = 0 - $treePopOnNewLine;
}
print STDERR "treePopOnNewLine -> $treePopOnNewLine\n" if ($ilcDebug);
}
} elsif ($parserState->{inComment}) {
my $linenum = $inputCounter + $fileoffset;
if (!$cpp_in_argparse) {
if ($nestedcommentwarn) {
warn("$fullpath:$linenum: warning: Nested comment found [1]. Ignoring.\n");
}
}
}
$parserState->{lastsymbol} = "";
$lastchar = $part;
last SWITCH;
};
($part eq $parseTokens{soc}) && do {
print STDERR "START OF MULTILINE COMMENT: CASE 26\n" if ($liteDebug);
print STDERR "SOC\n" if ($localDebug);
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{inString})) {
$parserState->{inComment} = 4;
$curline = spacefix($curline, $part, $lastchar);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) {
$treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [14]\n"; }
}
} elsif ($parserState->{inComment}) {
my $linenum = $inputCounter + $fileoffset;
if ($nestedcommentwarn) {
warn("$fullpath:$linenum: warning: Nested comment found [2]. Ignoring.\n");
}
}
$parserState->{lastsymbol} = "";
$lastchar = $part;
last SWITCH;
};
($part eq $parseTokens{eoc}) && do {
print STDERR "END OF MULTILINE COMMENT: CASE 27\n" if ($liteDebug);
print STDERR "EOC\n" if ($localDebug);
if ($parserState->{inComment} && !($parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{inString})) {
$parserState->{inComment} = 0;
$parserState->{leavingComment} = 1;
$curline = spacefix($curline, $part, $lastchar);
$ppSkipOneToken = 1;
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) {
my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
if (!$parserState->{seenBraces}) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
$treeCur = $treeCur->lastSibling();
if (!$parserState->{seenBraces}) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
print STDERR "TSPOP [6]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
} elsif (!$parserState->{inComment} && !$parserState->{inInlineComment} && !$parserState->{inString} && !$parserState->{inChar} && !$inRegexp) {
my $linenum = $inputCounter + $fileoffset;
warn("$fullpath:$linenum: warning: Unmatched close comment tag found. Ignoring.\n");
} elsif ($parserState->{inInlineComment}) {
my $linenum = $inputCounter + $fileoffset;
if ((1 || $nestedcommentwarn) && (!$HeaderDoc::running_test)) {
warn("$fullpath:$linenum: warning: Nested comment found [3]. Ignoring.\n");
}
}
$parserState->{lastsymbol} = "";
$lastchar = $part;
last SWITCH;
};
((($part eq "(" && (!$parserState->{inCase})) || (($parserState->{pendingBracedParameters} == 1) && casecmp($part, $parseTokens{lbrace}, $case_sensitive)))) && do {
print STDERR "OPEN PAREN: CASE 28\n" if ($liteDebug);
my @tempppl = undef;
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && !($inRegexp && ($regexpNoInterpolate || ($inRegexpFirstPart != 1)))) {
if ((!$parserState->isQuoted($lang, $sublang)) && (!$inRegexpCharClass)) {
my $oldParsedParamParse = $parserState->{parsedParamParse};
if ((!(scalar(@braceStack)-$parserState->{initbsCount})) && (!$parserState->{valuepending})) {
if ($parserState->{pendingBracedParameters}) {
$parserState->{startOfDec} = 0;
print STDERR "SET pendingBracedParameters -> 2\n" if ($parseDebug);
$parserState->{pendingBracedParameters} = 2;
}
if ($parserState->{occmethod} && !$parserState->{occmethodreturntype}) {
$parserState->{gatheringObjCReturnType}++;
} elsif ($pascal && $parserState->{sodclass} eq "function") {
$parserState->{parsedParamParse} = 2;
} elsif ($sublang eq "tcl") {
$parserState->{parsedParamParse} = 6;
} elsif ($sublang eq "MIG") {
$parserState->{parsedParamParse} = 2;
} else {
$parserState->{parsedParamParse} = 4;
}
print STDERR "parsedParamParse -> $parserState->{parsedParamParse}"."[lparen]\n" if ($parmDebug);
print STDERR "parsedParamList wiped\n" if ($parmDebug);
@tempppl = @{$parserState->{parsedParamList}};
@{$parserState->{parsedParamList}} = ();
$parsedParam = "";
}
$parserState->{onlyComments} = 0;
print STDERR "[i]onlyComments -> 0\n" if ($macroDebug);
if ($parserState->{simpleTypedef} && !(scalar(@braceStack)- $parserState->{initbsCount})) {
$parserState->{simpleTypedef} = 0;
$parserState->{simpleTDcontents} = "";
print STDERR "Setting typedef sodname to ".$parserState->{lastsymbol}."\n" if ($localDebug || $sodDebug);
$parserState->{sodname} = $parserState->{lastsymbol};
$parserState->{sodclass} = "function";
print STDERR "sodclass -> function (implicit)[4]\n" if ($sodDebug);
if (!$parserState->{freezereturn} && $parserState->{hollow} && !$parserState->{inComment} && !$parserState->{leavingComment}) {
$parserState->{returntype} = "$declaration$curline";
print STDERR "APPENDING TO RETURNTYPE: NOW \"$parserState->{returntype}\".\n" if ($retDebug);
} elsif (!$parserState->{freezereturn} && !$parserState->{hollow} && !$parserState->{inComment} && !$parserState->{leavingComment}) {
$parserState->{returntype} = "$curline";
print STDERR "REPLACING RETURNTYPE: NOW \"$parserState->{returntype}\".\n" if ($retDebug);
$declaration = "";
}
}
$parserState->{posstypesPending} = 0;
if ($parserState->{callbackNamePending} == 2) {
$parserState->{callbackNamePending} = 3;
print STDERR "callbackNamePending -> 3\n" if ($localDebug || $cbnDebug);
}
print STDERR "lparen\n" if ($localDebug);
print STDERR "WFTI: ".$parserState->{waitingForTypeInformation}."\n" if ($localDebug || $parseDebug);
if ($pascal && ($parserState->{waitingForTypeInformation} == 1) && ((scalar(@braceStack)-$parserState->{initbsCount}) == 0)) {
print STDERR "Setting sodclass to 'enum'." if ($sodDebug || $localDebug);
$parserState->{waitingForTypeInformation} = 3;
$parserState->{sodclass} = "enum";
print STDERR "sodclass -> enum (implicit)[5]\n" if ($sodDebug);
}
if ($parserState->{cbsodname} && (scalar(@braceStack)-$parserState->{initbsCount}) == 0) {
if (!$parserState->{functionReturnsCallback}) {
$parserState->{cbsodname} = "";
} else {
@{$parserState->{parsedParamList}} = @tempppl;
$parserState->{functionReturnsCallback}--;
print STDERR "parsedParamList restored\n" if ($parmDebug);
}
}
if ((scalar(@braceStack)-$parserState->{initbsCount}) == 1) {
if ($parserState->{callbackName}) {
$parserState->{cbsodname} = $parserState->{callbackName};
$parserState->{sodclass} = "function";
print STDERR "sodclass -> function (implicit)[6]\n" if ($sodDebug);
$parserState->{functionReturnsCallback}++;
print STDERR "Function returning callback. NAME: $parserState->{cbsodname}\n" if ($parmDebug || $localDebug || $parseDebug);
print STDERR "parsedParamParse -> 4[callback]\n" if ($parmDebug);
$parserState->{parsedParamParse} = 4;
print STDERR "parsedParamList wiped\n" if ($parmDebug);
@tempppl = @{$parserState->{parsedParamList}};
@{$parserState->{parsedParamList}} = ();
$parsedParam = "";
}
}
if ($parserState->{inOperator} == 1) {
$parserState->{inOperator} = 2;
}
push(@parsedParamParseStack, $oldParsedParamParse);
push(@braceStack, $part); pbs(@braceStack);
print STDERR "PUSHED $part ONTO BRACESTACK [4]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [15]\n"; }
}
$curline = spacefix($curline, $part, $lastchar);
print STDERR "LASTCHARCHECK: \"$lastchar\" \"$lastnspart\" \"$curline\".\n" if ($localDebug);
if ($lastnspart eq ")") { print STDERR "HERE: DEC IS $declaration\nENDDEC\nCURLINE IS $curline\nENDCURLINE\n" if ($localDebug);
print STDERR "SBS: ".scalar(@braceStack)."\n" if ($localDebug);
if ($declaration =~ /.*\n(.*?)\n$/so) {
my $lastline = $1;
print STDERR "LL: $lastline\nLLDEC: $declaration" if ($localDebug);
$declaration =~ s/(.*)\n(.*?)\n$/$1\n/so;
$curline = "$lastline $curline";
$curline =~ s/^\s*//so;
$prespace -= 4;
$prespaceadjust += 4;
$forcenobreak = 1;
print STDERR "NEWDEC: $declaration\nNEWCURLINE: $curline\n" if ($localDebug);
} elsif (length($declaration) && $callback_typedef_and_name_on_one_line) {
print STDERR "SCARYCASE\n" if ($localDebug);
$declaration =~ s/\n$//so;
$curline = "$declaration $curline";
$declaration = "";
$prespace -= 4;
$prespaceadjust += 4;
$forcenobreak = 1;
}
} else { print STDERR "OPARENLC: \"$lastchar\"\nCURLINE IS: \"$curline\"\n" if ($localDebug);}
$parserState->{lastsymbol} = "";
$lastchar = $part;
if ($parserState->{startOfDec} == 2) {
if ($HeaderDoc::parsing_man_pages) {
$parserState->{declarationEndsAtNewLine} = 1;
}
$parserState->{sodclass} = "function";
print STDERR "sodclass -> function (implicit)[7]\n" if ($sodDebug);
$parserState->{freezereturn} = 1;
$parserState->{returntype} =~ s/^\s*//so;
$parserState->{returntype} =~ s/\s*$//so;
}
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [3]\n" if ($localDebug);
if ($curline !~ /\S/o) {
$prespace += 4;
print STDERR "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print STDERR "PSA: $prespaceadjust\n" if ($localDebug);
}
if ($inRegexp) {
print STDERR "PUSHING $part ONTO REGEXPSTACK [6]\n" if ($localDebug || $parseDebug || $regexpDebug);
push(@regexpStack, $part);
}
}
}
print STDERR "OUTGOING CURLINE: \"$curline\"\n" if ($localDebug);
last SWITCH;
};
((($part eq ")" && (!$parserState->{inCase})) || ($parserState->isRightBrace($part, $lang, \%parseTokens, $case_sensitive) && ($parserState->{pendingBracedParameters} == 2)))) && do {
print STDERR "CLOSE PAREN: CASE 29\n" if ($liteDebug);
print STDERR "TOP OF RE STACK IS: \"".peek(\@regexpStack)."\"\n" if ($localDebug || $parseDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) && !($inRegexp && ($regexpNoInterpolate || ($inRegexpFirstPart != 1)) && (peek(\@regexpStack) ne "("))) {
print STDERR "PAST FIRST CHECK\n" if ($localDebug || $parseDebug);
if ((!$parserState->isQuoted($lang, $sublang)) && (!$inRegexpCharClass)) {
my $opentoken = "(";
if (((scalar(@braceStack)-$parserState->{initbsCount} - $parserState->{functionReturnsCallback}) == 1)) {
if ($parserState->{pendingBracedParameters}) {
$parserState->{pendingBracedParameters} = 0;
$opentoken = "{";
}
if ($parserState->{gatheringObjCReturnType}) {
$parserState->{gatheringObjCReturnType}--;
if ($parserState->{gatheringObjCReturnType} == 1) {
$parserState->{gatheringObjCReturnType} = 0;
}
}
if ($parserState->{parsedParamParse}) {
$parserState->{parsedParamParse} = 0;
print STDERR "parsedParamParse -> 0[rparen]\n" if ($parmDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if ($parsedParam ne "void") {
push(@{$parserState->{parsedParamList}}, $parsedParam);
print STDERR "pushed $parsedParam into parsedParamList [1]\n" if ($parmDebug);
}
$parsedParam = "";
}
}
$parserState->{onlyComments} = 0;
print STDERR "[j]onlyComments -> 0\n" if ($macroDebug);
print STDERR "rparen\n" if ($localDebug);
my $test = "";
my $parenRegexp = 0;
if ($inRegexp && ($regexpStack[0] eq "(")) {
$parenRegexp = 0;
}
if (!$parenRegexp) {
$test = pop(@braceStack); pbs(@braceStack);
$parserState->{parsedParamParse} = pop(@parsedParamParseStack);
print STDERR "POPPED $test FROM BRACESTACK [4]\n" if ($macroDebug || $braceDebug);
}
print STDERR "RPAREN SEENBRACES: ".$parserState->{seenBraces}."\n" if ($localDebug || $parserStateInsertDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
if (!$parserState->{seenBraces}) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
$treeCur = $treeCur->lastSibling();
if (!$parserState->{seenBraces}) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
print STDERR "TSPOP [6a]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if (!$parenRegexp) {
if (!($test eq $opentoken)) {
warn("$fullpath:$inputCounter: warning: Parentheses do not match.\nWe may have a problem.\n");
warn("Declaration to date: $declaration$curline\n");
}
}
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$lastchar = $part;
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [4]\n" if ($localDebug);
if ($curline !~ /\S/o) {
$prespace -= 4;
print STDERR "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust -= 4;
print STDERR "PSA: $prespaceadjust\n" if ($localDebug);
}
if ($inRegexp && (!$regexpNoInterpolate || ($inRegexpFirstPart == 1))) {
my $temp = pop(@regexpStack);
print STDERR "popped $temp FROM REGEXPSTACK\n" if ($localDebug || $parseDebug || $regexpDebug);
if ($temp ne "(") {
warn("Parentheses do not match in regular expression. We may have a problem.\n");
warn("Line is \"$line\"\n") if ($regexpDebug);
}
}
last SWITCH;
}
}
};
(($lang ne "perl" || !($parserState->{inTemplate} || $inRegexp || $leavingRegexp)) && $parserState->isLeftBrace($part, $lang, \%parseTokens, $case_sensitive, scalar(@braceStack))) && do {
my $brctoken = $part;
print STDERR "IRC ".$parserState->{inRubyClass}."\n" if ($rubyDebug || $parseDebug);
if ($parseTokens{classisbrace} && $parserState->{sodclass} eq "class" && (!$parserState->{inRubyClass}) && $part =~ /[\n\r]/) {
print STDERR "SET IRC -> 1\n" if ($rubyDebug || $parseDebug);;
$parserState->{inRubyClass} = 1;
$brctoken = "class";
} elsif ($parseTokens{functionisbrace} && $parserState->{pushedfuncbrace} == 1) {
$parserState->{pushedfuncbrace} = 2;
$brctoken = $parseTokens{sofunction};
}
my $oldParsedParamParse = $parserState->{parsedParamParse};
print STDERR "LEFT BRACE: CASE 30\n" if ($liteDebug);
if ($lang eq "applescript" && $pushParserStateAtBrace) {
$pushParserStateAtBrace = 0;
$pushParserStateAfterToken = 1;
}
if ($parserState->{onlyComments} && !$parserState->{inComment} && !$parserState->{inInlineComment} && !$parserState->{inChar} && !$inRegexp && !scalar(@parserStack) && !$parserState->{INIF} && !$tempInIf && ($lang ne "applescript")) {
print STDERR "BAILING NOW\n" if ($externCDebug);
$continue_no_return = 1;
print STDERR "CONTINUE -> 0 [NORETURN]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
$continue = 0;
}
if ($parserState->{inGiven}) {
if (length($parsedParam)) { push(@{$parserState->{parsedParamList}}, $parsedParam); }
print STDERR "PUSHING \"$parsedParam\" onto parsed parameters list ()\n" if ($parseDebug || $asDebug);
$parsedParam = "";
}
if ($parserState->{onlyComments} && !$parserState->{inComment} && !$parserState->{inInlineComment} && !$parserState->{inChar} && !$inRegexp && scalar(@parserStack) && $lang ne "applescript") {
print STDERR "NOINSERT\n" if ($parserStackDebug);
$pushParserStateAtBrace = 1;
$parserState->{noInsert} = 1;
}
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $inRegexp)) {
$parserState->{bracePending} = 0;
print STDERR "bracePending -> 0 [brace]\n" if ($localDebug);
$parserState->{onlyComments} = 0;
print STDERR "[k]onlyComments -> 0\n" if ($macroDebug);
push(@{$parserState->{parsedParamStateAtBrace}}, $parserState->{parsedParamParse});
push(@{$parserState->{parsedParamAtBrace}}, $parsedParam);
$parsedParam = "";
if (scalar(@{$parserState->{parsedParamList}})) {
foreach my $node (@{$parserState->{parsedParamList}}) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@{$parserState->{pplStack}}, $node)
}
}
@{$parserState->{parsedParamList}} = ();
print STDERR "parsedParamList pushed [2]\n" if ($parmDebug);
}
if (!$pushParserStateAtBrace && !$parserState->{inClass}) {
if ($parserState->{inEnum}) {
$parserState->{parsedParamParse} = 4;
} else {
$parserState->{parsedParamParse} = 2;
}
print STDERR "parsedParamParse -> $parserState->{parsedParamParse}"."[lbrace]\n" if ($parmDebug);
}
if (!$parserState->{inClass} && ($parserState->{sodclass} eq "function" || $parserState->{inOperator} || $parserState->{occmethod})) {
print STDERR "seenBraces -> 1 [2]\n" if ($parseDebug || $braceDebug);
$parserState->{seenBraces} = 1;
if (!$parserState->{stackFrozen}) {
@{$parserState->{freezeStack}} = @{$parserState->{pplStack}};
$parserState->{frozensodname} = $parserState->{sodname};
$parserState->{stackFrozen} = 1;
}
@{$parserState->{pplStack}} = ();
}
$parserState->{posstypesPending} = 0;
$parserState->{namePending} = 0;
$parserState->{callbackNamePending} = -1;
$parserState->{simpleTypedef} = 0;
$parserState->{simpleTDcontents} = "";
print STDERR "callbackNamePending -> -1\n" if ($localDebug || $cbnDebug);
print STDERR "lbrace\n" if ($localDebug);
push(@parsedParamParseStack, $oldParsedParamParse);
push(@braceStack, $brctoken); pbs(@braceStack);
print STDERR "PUSHED $brctoken ONTO BRACESTACK [5]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !$parserState->{seenBraces}) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [16]\n"; }
print STDERR "TN -> 1\n" if ($localDebug);
}
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$lastchar = $part;
if ($parserState->{INMODULE} == 2) {
$treepart = " ";
}
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [5]\n" if ($localDebug);
if ($curline !~ /\S/o) {
$prespace += 4;
print STDERR "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print STDERR "PSA: $prespaceadjust\n" if ($localDebug);
}
}
last SWITCH;
};
(($parserState->isRightBrace($part, $lang, \%parseTokens, $case_sensitive) || $parserState->{inrbraceargument}) && ($parserState->{pendingBracedParameters} != 2) && ($lang ne "perl" || !($parserState->{inTemplate} || $inRegexp || $leavingRegexp))) && do {
print STDERR "RIGHT BRACE: CASE 31\n" if ($liteDebug);
print STDERR "INBRACEARGUMENT: ".$parserState->{inrbraceargument}."\n" if ($parserStateInsertDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $inRegexp)) {
my $oldOC = $parserState->{onlyComments};
print STDERR "rbrace???\n" if ($localDebug);
print STDERR "[l]onlyComments -> 0\n" if ($macroDebug);
if ($ruby) { $parserState->{followingrubyrbrace} = 1; }
if (($parseTokens{rbracetakesargument}) && (!$parserState->{inrbraceargument})) {
$parserState->{inrbraceargument} = 1;
} elsif ($parserState->{inrbraceargument} && $part =~ /\w/) {
$parserState->{inrbraceargument}--;
if ($parserState->{seenBraces}) { $trailingHide = 1; }
}
if ($parserState->{inrbraceargument}) {
print STDERR "Waiting for rbrace argument\n" if ($asDebug || $parserStackDebug || $parseDebug || $braceDebug);
} else {
print STDERR "INRBRACEARGUMENT: ".$parserState->{inrbraceargument}."\n" if ($asDebug || $parserStackDebug || $parseDebug || $braceDebug);
my $bsCount = scalar(@braceStack);
print STDERR "SPS: ".scalar(@parserStack)." BSC: ".$bsCount." IBSC: ".$parserState->{initbsCount}."\n" if ($rubyDebug || $parseDebug);
if (scalar(@parserStack) && !($bsCount - $parserState->{initbsCount})) {
print STDERR "parserState: ENDOFSTATE\n" if ($parserStackDebug);
if ($parserState->{inrbraceargument}) {
print STDERR "parserState insertion skipped[RBRACE, INARG]\n" if ($parserStackDebug || $parserStateInsertDebug);
} elsif ($parserState->{noInsert} || $oldOC) {
print STDERR "parserState insertion skipped[RBRACE]\n" if ($parserStackDebug || $parserStateInsertDebug);
} elsif ($parserState->{hollow}) {
print STDERR "inserted parser state into tree [RBRACE]\n" if ($parserStateInsertDebug);
my $treeRef = $parserState->{hollow};
print STDERR "Last tree node set to $treeCur [5]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$treeRef->addRawParsedParams(\@{$parserState->{parsedParamList}});
$treeRef->parserState($parserState);
} else {
warn "Couldn't insert info into parse tree[1].\n";
}
print STDERR "parserState popped from parserStack[rbrace]\n" if ($parserStackDebug);
$parserState = pop(@parserStack) || $parserState;
$declaration = $parserState->{storeDec}.$declaration;
if ($parserState->{INMODULE} == 2) {
print STDERR "CURRENT: ".$treeCur->{TOKEN}."\n" if ($localDebug);
$part = "";
print STDERR "INMODULE -> 3\n" if ($localDebug || $moduleDebug);
$parserState->{INMODULE} = 3;
print STDERR "CONTINUE -> 0 [1aMODULE]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
$parserState->{noInsert} = 0;
$continue = 0;
print STDERR "AT END. STACK COUNT: ".scalar(@parserStack)."\n" if ($parserStackDebug || $localDebug);
}
if ($lang eq "php" || ($lang eq "C" && $sublang eq "IDL") || ($lang eq "java" && $sublang eq "java") || $ruby || ($lang eq "tcl") || ($lang eq "applescript")) {
if (scalar(@braceStack) == 1) {
print STDERR "CONTINUE -> 0 [1aOutOfBraces]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
$continue = 0;
} elsif ($lang eq "applescript" && (scalar(@braceStack)-$parserState->{initbsCount}) == 1) {
print STDERR "Terminating nested class at newline.\n"; $parserState->{declarationEndsAtNewLine} = 1;
}
}
if ($parserState->{noInsert} && scalar(@parserStack)) {
print STDERR "parserState: Hit me.\n" if ($localDebug);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack) - 1;
}
} else {
print STDERR "NO CHANGE IN PARSER STATE STACK (nPARSERSTACK = ".scalar(@parserStack).", $bsCount != $parserState->{initbsCount})\n" if ($parseDebug || $parserStackDebug);
}
print STDERR "Ruby stopcheck: ".scalar(@braceStack)." - ".$parserState->{initbsCount}."\n" if ($rubyDebug || $parseDebug);
if ((scalar(@braceStack)-$parserState->{initbsCount}) == 1) {
if ($ruby) {
print STDERR "Ruby stopearly: ".scalar(@braceStack)." - ".$parserState->{initbsCount}."\n" if ($rubyDebug || $parseDebug);;
$parserState->{newlineIsSemi} = 1;
}
$parserState->{parsedParamParse} = 0;
print STDERR "parsedParamParse -> 0[rbrace]\n" if ($parmDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) {
push(@{$parserState->{parsedParamList}}, $parsedParam);
print STDERR "pushed $parsedParam into parsedParamList [1b]\n" if ($parmDebug);
}
$parsedParam = "";
} else {
$parserState->{parsedParamParse} = pop(@{$parserState->{parsedParamStateAtBrace}}); $parsedParam = pop(@{$parserState->{parsedParamAtBrace}});
print STDERR "parsedParamParse -> $parserState->{parsedParamParse}"."[rbrace2]\n" if ($parmDebug);
}
if (scalar(@{$parserState->{parsedParamList}})) {
foreach my $node (@{$parserState->{parsedParamList}}) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@{$parserState->{pplStack}}, $node)
}
}
@{$parserState->{parsedParamList}} = ();
print STDERR "parsedParamList pushed [3]\n" if ($parmDebug);
}
print STDERR "rbrace\n" if ($localDebug);
my $test = pop(@braceStack); pbs(@braceStack);
my $temp = pop(@parsedParamParseStack);
if ($temp) {
if ($temp == 1) { $temp = 2; }
elsif ($temp == 3) { $temp = 4; }
if ($temp != $parserState->{parsedParamParse} && $parmDebug) {
warn("Changing PPP from ".$parserState->{parsedParamParse}." to $temp\n");
}
$parserState->{parsedParamParse} = $temp;
}
print STDERR "POPPED $test FROM BRACESTACK [5]\n" if ($macroDebug || $braceDebug);
if (($HeaderDoc::includeFunctionContents || !($parserState->{seenBraces} || $trailingHide)) && (!$parserState->{inrbraceargument})) { warn("TSPOP FOR NOT SEEN BRACES\n") if ($parserStateInsertDebug || $treeDebug);
my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
if (!($parserState->{seenBraces} || $trailingHide)) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
$treeCur = $treeCur->lastSibling();
if (!($parserState->{seenBraces} || $trailingHide)) {
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
}
print STDERR "TSPOP [7]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if (!($test eq "$parseTokens{lbrace}") && (!length($parseTokens{structname}) || (!($test eq $parseTokens{structname}) && $parseTokens{structisbrace}))) {
warn("$fullpath:$inputCounter: warning: Braces do not match (top of brace stack\nis \"$test\").We may have a problem.\n");
warn("Declaration to date: $declaration$curline\n");
}
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$lastchar = $part;
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [6]\n" if ($localDebug);
if ($curline !~ /\S/o) {
$prespace -= 4;
print STDERR "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust -= 4;
print STDERR "PSA: $prespaceadjust\n" if ($localDebug);
}
}
}
last SWITCH;
};
(length($part) && length($nextpart) && ((length($parseTokens{propname}) && $parseTokens{propname} =~ /\@/) || length($parseTokens{objcdynamicname}) || length($parseTokens{objcsynthesizename}) || length($classregexp) || (length($accessregexp) && $accessregexp =~ /\@/)) && $part =~ /^\@$/ && !$parserState->{inComment} && !$parserState->{inChar} && !$parserState->{inString} && !$parserState->{inInlineComment}) && do {
print STDERR "PROPERTY PREPEND AT (\@): CASE 32\n" if ($liteDebug);
my $temp = "\@".$nextpart;
if ($temp =~ /$accessregexp/) {
print STDERR "MERGE $part $nextpart\n" if ($localDebug);
$nextpart = "\@".$nextpart;
$parserState->{classIsObjC} = 1;
} elsif ($temp =~ /$classregexp/) {
$nextpart = "\@".$nextpart;
$parserState->{classIsObjC} = 1;
} elsif ($temp =~ /$classclosebraceregexp/) {
$nextpart = "\@".$nextpart;
} elsif ($temp eq $parseTokens{propname}) {
$part = "";
print STDERR "MERGE $part $nextpart\n" if ($localDebug);
$nextpart = "\@".$nextpart;
} elsif (length($requiredregexp) && $temp =~ /$requiredregexp/) {
$part = "";
print STDERR "MERGE $part $nextpart\n" if ($localDebug);
$nextpart = "\@".$nextpart;
} elsif ($temp eq $parseTokens{objcdynamicname}) {
$part = "";
print STDERR "MERGE $part $nextpart\n" if ($localDebug);
$nextpart = "\@".$nextpart;
} elsif ($temp eq $parseTokens{objcsynthesizename}) {
$part = "";
print STDERR "MERGE $part $nextpart\n" if ($localDebug);
$nextpart = "\@".$nextpart;
}
next SWITCH;
};
($modules_are_special && !$parserState->{inTemplate} && !$parserState->{inComment} && !$parserState->{inInlineComment} && !$parserState->{inString} && !$parserState->{inChar} && length($moduleregexp) && $part =~ /$moduleregexp/) && do {
print STDERR "INMODULE -> 1\n" if ($localDebug || $moduleDebug);
$parserState->{INMODULE} = 1;
print STDERR "MODULE START TOKEN: CASE 32-M-1\n" if ($localDebug || $liteDebug);
};
(length($classclosebraceregexp) && ($part =~ /$classclosebraceregexp/) && !$parserState->{inComment} && !$parserState->{inChar} && !$parserState->{inString} && !$parserState->{inInlineComment}) && do {
print STDERR "CLASS CLOSE BRACE: CASE 33\n" if ($liteDebug);
if ($part ne peekmatch(\@braceStack, $lang, $fullpath, $inputCounter)) {
warn("$fullpath:inputCounter: warning: Class braces do not match.\nWe may have a problem.\n");
}
print STDERR "seenBraces -> 1 [3]\n" if ($parseDebug || $braceDebug);
$parserState->{seenBraces} = 1;
my $temp = pop(@braceStack);
$parserState->{parsedParamParse} = pop(@parsedParamParseStack);
print STDERR "POPPED $temp FROM BRACESTACK [6]\n" if ($macroDebug || $braceDebug);
my $tempCur = $treeCur->addSibling($part, 0); $treeSkip = 1;
if ($HeaderDoc::includeFunctionContents && $reMark) {
$tempCur->{RE_STATE} = $reMark;
}
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [6]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
$part =~ s/^\@//s;
if ( 1 || $nextpart ne ";") {
if (scalar(@parserStack) == 1) {
$parserState = pop(@parserStack) || $parserState;
$declaration = $parserState->{storeDec}.$declaration;
$continue = 0;
print STDERR "CONTINUE -> 0 [occend]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
} else {
if (!$parserState->{onlyComments}) {
if ($parserState->{noInsert}) {
print STDERR "parserState insertion skipped[\@end]\n" if ($parserStackDebug);
} elsif ($parserState->{hollow}) {
print STDERR "inserted parser state into tree [\@end]\n" if ($parserStateInsertDebug);
my $treeRef = $parserState->{hollow};
print STDERR "Last tree node set to $treeCur [6]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$treeRef->addRawParsedParams(\@{$parserState->{parsedParamList}});
$treeRef->parserState($parserState);
} else {
warn "Couldn't insert info into parse tree[2].\n";
}
print STDERR "parserState: Created parser state[1].\n" if ($parserStackDebug);
print STDERR "CURLINE CLEAR[PRS2]\n" if ($localDebug);
$curline = "";
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
}
print STDERR "parserState popped from parserStack[\@end]\n" if ($parserStackDebug);
$parserState = pop(@parserStack) || $parserState;
$declaration = $parserState->{storeDec}.$declaration;
}
}
};
(!$parserState->{inTemplate} && !$parserState->{inComment} && !$parserState->{inInlineComment} && !$parserState->{inString} && !$parserState->{inChar} && length($classregexp) && $part =~ /$classregexp/) && do {
print STDERR "START OF CLASS: CASE 34\n" if ($liteDebug);
if ($parseTokens{superclasseswithcurlybraces}) {
$parserState->{pendingBracedParameters} = 1;
}
print STDERR "INCLASSCHECK AFTERNL: ".$parserState->{afterNL}."\n" if ($parseDebug);
my $localclasstype = $1;
if ($part =~ /^\@/) { $part =~ s/^\@//s; }
if ((($lang eq "applescript") && $parserState->{afterNL}) || (($lang ne "applescript") && !(scalar(@braceStack)-$parserState->{initbsCount}))) {
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || ($parserState->{inChar} && $lang ne "applescript"))) {
print STDERR "ITISACLASS\n" if ($localDebug || $classDebug);
if (!length($parserState->{sodclass}) && !$parserState->{inTypedef}) {
print STDERR "GOOD.\n" if ($localDebug);
$parserState->{inClass} = 1;
print STDERR "inClass -> 1 [7]\n" if ($classDebug);
$pushParserStateAtBrace = 1;
if ($localclasstype =~ /\@interface/) {
$parserState->{inClass} = 2;
print STDERR "inClass -> 2 [8]\n" if ($classDebug);
$pushParserStateAtBrace = 0;
} elsif ($localclasstype =~ /\@protocol/) {
$pushParserStateAtBrace = 0;
$pushParserStateAfterWordToken = 0;
$parserState->{inClass} = 0;
print STDERR "inClass -> 0 [9]\n" if ($classDebug);
$parserState->{inProtocol} = 1;
} elsif ($localclasstype =~ /\@implementation/) {
$pushParserStateAtBrace = 0;
$pushParserStateAfterWordToken = 2;
}
$parserState->{sodclass} = "class";
print STDERR "sodclass -> class (explicit)[8]\n" if ($sodDebug);
$parserState->{classtype} = $localclasstype;
if (length($parserState->{sodtype})) {
$parserState->{preclasssodtype} = $parserState->{sodtype} . " " . $part;
} else {
$parserState->{preclasssodtype} = $part;
}
$parserState->{sodtype} = "";
$parserState->{startOfDec} = 1;
$parserState->{sodtypeclasstoken} = $part;
print STDERR "startOfDec -> 1 [7]\n" if ($localDebug);
$parserState->{onlyComments} = 0;
print STDERR "[m]onlyComments -> 0\n" if ($macroDebug);
$continuation = 1;
if (length($classbraceregexp) && ($localclasstype =~ /$classbraceregexp/)) {
print STDERR "CLASS ($localclasstype) IS A BRACE.\n" if ($localDebug);
push(@parsedParamParseStack, $parserState->{parsedParamParse});
push(@braceStack, $localclasstype); pbs(@braceStack);
print STDERR "PUSHED $localclasstype ONTO BRACESTACK [6]\n" if ($macroDebug || $braceDebug);
$treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [17]\n"; }
}
($lang, $sublang) = getLangAndSublangFromClassType($localclasstype, $lang, $sublang);
$HeaderDoc::lang = $lang;
$HeaderDoc::sublang = $sublang;
%parseTokens = %{parseTokens($lang, $sublang)};
$labelregexp = $parseTokens{labelregexp};
$classregexp = $parseTokens{classregexp};
$classbraceregexp = $parseTokens{classbraceregexp};
$classclosebraceregexp = $parseTokens{classclosebraceregexp};
$accessregexp = $parseTokens{accessregexp};
$requiredregexp = $parseTokens{requiredregexp};
$moduleregexp = $parseTokens{moduleregexp};
$macrore_pound = macroRegexpFromList($parseTokens{macronames}, 1);
$macrore_nopound = macroRegexpFromList($parseTokens{macronames}, 2);
$regexppattern = $parseTokens{regexppattern};
$singleregexppattern = $parseTokens{singleregexppattern};
$regexpfirstcharpattern = $parseTokens{regexpfirstcharpattern};
$regexpcharpattern = $parseTokens{regexpcharpattern};
$regexpAllowedAfter = $parseTokens{regexpAllowedAfter};
$TCLregexpcommand = $parseTokens{TCLregexpcommand};
print STDERR "ARP: $accessregexp\n" if ($localDebug);
last SWITCH;
} else {
($lang, $sublang) = getLangAndSublangFromClassType($localclasstype, $lang, $sublang);
$HeaderDoc::lang = $lang;
$HeaderDoc::sublang = $sublang;
%parseTokens = %{parseTokens($lang, $sublang)};
$labelregexp = $parseTokens{labelregexp};
$classregexp = $parseTokens{classregexp};
$classbraceregexp = $parseTokens{classbraceregexp};
$classclosebraceregexp = $parseTokens{classclosebraceregexp};
$accessregexp = $parseTokens{accessregexp};
$requiredregexp = $parseTokens{requiredregexp};
$moduleregexp = $parseTokens{moduleregexp};
$macrore_pound = macroRegexpFromList($parseTokens{macronames}, 1);
$macrore_nopound = macroRegexpFromList($parseTokens{macronames}, 2);
$regexppattern = $parseTokens{regexppattern};
$singleregexppattern = $parseTokens{singleregexppattern};
$regexpfirstcharpattern = $parseTokens{regexpfirstcharpattern};
$regexpcharpattern = $parseTokens{regexpcharpattern};
$regexpAllowedAfter = $parseTokens{regexpAllowedAfter};
$TCLregexpcommand = $parseTokens{TCLregexpcommand};
print STDERR "ARP: $accessregexp\n" if ($localDebug);
last SWITCH;
}
} else {
print STDERR "STR: ".$parserState->{inString}." COM: ".$parserState->{inComment}." ILC: ".$parserState->{inInlineComment}." CHAR: ".$parserState->{inChar}." LANG: ".$lang."\n";
}
}
};
($part eq $parseTokens{objcdynamicname}) && do {
print STDERR "PROPERTY: CASE 35\n" if ($liteDebug);
print STDERR "PROPERTY FOUND\n" if ($localDebug);
$parserState->{isProperty} = 1; last SWITCH;
};
($part eq $parseTokens{objcsynthesizename}) && do {
print STDERR "PROPERTY: CASE 35\n" if ($liteDebug);
print STDERR "PROPERTY FOUND\n" if ($localDebug);
$parserState->{isProperty} = 1; last SWITCH;
};
($part eq $parseTokens{propname}) && do {
print STDERR "PROPERTY: CASE 35\n" if ($liteDebug);
print STDERR "PROPERTY FOUND\n" if ($localDebug);
$parserState->{isProperty} = 1; last SWITCH;
};
($part eq $parseTokens{structname} || $part eq $parseTokens{enumname} || $part eq $parseTokens{unionname}) && do {
print STDERR "STRUCT/ENUM/UNION: CASE 36\n" if ($liteDebug);
if ((!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) &&
(!(scalar(@braceStack)-$parserState->{initbsCount}))) {
if ($parseTokens{structisbrace}) {
if ($parserState->{sodclass} eq "function") {
print STDERR "seenBraces -> 1 [4]\n" if ($parseDebug || $braceDebug);
$parserState->{seenBraces} = 1;
if (!$parserState->{stackFrozen}) {
@{$parserState->{freezeStack}} = @{$parserState->{pplStack}};
$parserState->{frozensodname} = $parserState->{sodname};
$parserState->{stackFrozen} = 1;
}
@{$parserState->{pplStack}} = ();
}
$parserState->{posstypesPending} = 0;
$parserState->{callbackNamePending} = -1;
$parserState->{simpleTypedef} = 0;
$parserState->{simpleTDcontents} = "";
print STDERR "callbackNamePending -> -1\n" if ($localDebug || $cbnDebug);
print STDERR "lbrace\n" if ($localDebug);
push(@parsedParamParseStack, $parserState->{parsedParamParse});
push(@braceStack, $part); pbs(@braceStack);
print STDERR "PUSHED $part ONTO BRACESTACK [7]\n" if ($macroDebug || $braceDebug);
if ($HeaderDoc::includeFunctionContents || !($parserState->{seenBraces} || $trailingHide)) { $treeNest = 1;
if ($treeDebug) { print STDERR "TS TREENEST -> 1 [18]\n"; }
}
$curline = spacefix($curline, $part, $lastchar);
$parserState->{lastsymbol} = "";
$lastchar = $part;
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [8]\n" if ($localDebug);
if ($curline !~ /\S/o) {
$prespace += 4;
print STDERR "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print STDERR "PSA: $prespaceadjust\n" if ($localDebug);
}
} else {
if (!$parserState->{simpleTypedef}) {
print STDERR "simpleTypedef -> 2\n" if ($localDebug);
$parserState->{simpleTypedef} = 2;
}
}
if ($part eq $parseTokens{enumname}) {
$parserState->{inEnum} = 1;
$parserState->{inUnion} = 0;
} elsif ($part eq $parseTokens{unionname}) {
$parserState->{inEnum} = 0;
$parserState->{inUnion} = 1;
} else {
$parserState->{inEnum} = 0;
$parserState->{inUnion} = 0;
}
$parserState->{onlyComments} = 0;
print STDERR "[n]onlyComments -> 0\n" if ($macroDebug);
$continuation = 1;
if ($parserState->{basetype} eq "") { $parserState->{basetype} = $part; }
if ($parserState->{typestring} eq "") { $parserState->{typestring} = $part; }
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inString} || $parserState->{inChar})) {
$parserState->{namePending} = 2;
print STDERR "namePending -> 2 [2]\n" if ($parseDebug);
if ($parserState->{posstypesPending}) { $parserState->{posstypes} .=" $part"; }
}
if ($parserState->{sodclass} eq "") {
$parserState->{startOfDec} = 0; $parserState->{sodname} = "";
print STDERR "startOfDec -> 0 [9]\n" if ($localDebug);
print STDERR "sodname cleared (seu)\n" if ($sodDebug);
}
$lastchar = $part;
}; }; ($part eq $parseTokens{typedefname}) && do {
print STDERR "TYPEDEF: CASE 37\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if (!(scalar(@braceStack)-$parserState->{initbsCount})) { $parserState->{callbackIsTypedef} = 1; $parserState->{inTypedef} = 1; }
$parserState->{onlyComments} = 0;
print STDERR "[o]onlyComments -> 0\n" if ($macroDebug);
$continuation = 1;
if ($parserState->{typestring} eq "") { $parserState->{typestring} = $part; }
$parserState->{simpleTypedef} = 1; print STDERR "simpleTypedef -> 1\n" if ($localDebug);
if ($part eq $parseTokens{typedefname}) {
if (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inString} || $parserState->{inChar})) {
if ($pascal) {
$parserState->{namePending} = 2;
$inPType = 1;
print STDERR "namePending -> 2 [3]\n" if ($parseDebug);
}
if ($parserState->{posstypesPending}) { $parserState->{posstypes} .=" $part"; }
if (!($parserState->{callbackNamePending})) {
print STDERR "callbackNamePending -> 1\n" if ($localDebug || $cbnDebug);
$parserState->{callbackNamePending} = 1;
}
}
}
if ($parserState->{sodclass} eq "") {
$parserState->{startOfDec} = 0; $parserState->{sodname} = "";
print STDERR "startOfDec -> 0 [10]\n" if ($localDebug);
print STDERR "sodname cleared ($parseTokens{typedefname})\n" if ($sodDebug);
}
$lastchar = $part;
}; };
($part eq $parseTokens{operator}) && do {
print STDERR "OPERATOR KEYWORD: CASE 38\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
$parserState->{inOperator} = 1;
$parserState->{sodname} = "";
$parserState->{sodtype} = $parserState->{returntype};
}
$parserState->{lastsymbol} = $part;
$lastchar = $part;
last SWITCH;
};
($part =~ /;/o || ($parserState->{newlineIsSemi} && (!$parserState->isQuoted($lang, $sublang)) && $part =~ /[\n\r]/)) && do {
print STDERR "SEMICOLON: CASE 39\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if ($lang eq "shell") {
if ($part eq ";;") {
$parserState->{afterSemi} = 2;
} elsif (!$parserState->{afterSemi}) {
$parserState->{afterSemi} = 1;
}
}
if ($parserState->{inTCLRegExpCommand}) {
$parserState->{inTCLRegExpCommand} = 0;
}
print STDERR "NOT IN STRING, CHAR, COMMENT, etc.\n" if ($localDebug);
if ($parserState->{parsedParamParse}) {
print STDERR "PPP IS $parserState->{parsedParamParse}.\n" if ($localDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) { push(@{$parserState->{parsedParamList}}, $parsedParam); }
print STDERR "pushed $parsedParam into parsedParamList [2semi]\n" if ($parmDebug);
$parsedParam = "";
}
print STDERR "PPP AT SEMI: $parserState->{parsedParamParse}\n" if ($parseDebug || $localDebug || $parmDebug);
if ($parserState->{parsedParamParse} <= 2) {
$parserState->{parsedParamParse} = 2;
print STDERR "parsedParamParse -> 2[semi]\n" if ($parmDebug);
$parserState->{freezereturn} = 1;
$parserState->{temponlyComments} = $parserState->{onlyComments};
print STDERR "[p]onlyComments -> 0\n" if ($macroDebug);
print STDERR "valuepending -> 0\n" if ($valueDebug);
$parserState->{valuepending} = 0;
} else {
if ($parmDebug) {
warn "WARNING: PPP AT SEMI NOT <= 2!\n";
}
}
$continuation = 1;
if ($parserState->{occmethod}) {
$prespaceadjust = -$prespace;
}
if (($part =~ /;/o && !$parserState->{inMacroLine} && !$parserState->{inMacro}) ||
($parserState->{newlineIsSemi} && $part =~ /[\n\r]/)) {
if ($parserState->{newlineIsSemi}) { $parserState->{newlineIsSemi} = 0; }
my $bsCount = scalar(@braceStack)-$parserState->{initbsCount};
print STDERR "INHERE BSC $bsCount\n" if ($rubyDebug || $parseDebug);
if (!$bsCount && !$parserState->{kr_c_function}) {
if ($parserState->{startOfDec} == 2 && !$pascal) {
$parserState->{sodclass} = "variable";
print STDERR "sodclass -> variable (implicit)[9]\n" if ($sodDebug);
$parserState->{startOfDec} = 1;
print STDERR "startOfDec -> 1 [11]\n" if ($localDebug);
} elsif (!($parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{inString})) {
$parserState->{startOfDec} = 1;
print STDERR "startOfDec -> 1 [12]\n" if ($localDebug);
}
}
if (!$bsCount) {
print STDERR "HERE BSC: $bsCount\n" if ($rubyDebug || $parseDebug);
$treeCur = $treeCur->addSibling($part); $treepart = " "; if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
if (0) {
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [8]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
while ($parserState->{treePopTwo}--) {
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [9]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
$parserState->{treePopTwo} = 0;
}
}
$lastchar = $part;
}; }; ((($part eq "=" && (!$parseTokens{assignmentwithcolon})) ||
($part eq ":" && ($parseTokens{assignmentwithcolon} == 1))) &&
($parserState->{lastsymbol} ne $parseTokens{operator}) && (!(($parserState->{inOperator} == 1) && $parserState->{lastsymbol} =~ /\W/ && $parserState->{lastsymbol} =~ /\S/)) && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) && do {
print STDERR "EQUALS: CASE 40\n" if ($liteDebug);
$parserState->{onlyComments} = 0;
print STDERR "[q]onlyComments -> 0\n" if ($macroDebug);
if ((($part eq "=" && (!$parseTokens{assignmentwithcolon})) ||
($part eq ":" && ($parseTokens{assignmentwithcolon} == 1))) &&
!(scalar(@braceStack)-$parserState->{initbsCount}) &&
$nextpart !~ /=/o && $lastchar !~ /=/o &&
$parserState->{sodclass} ne "function" && !$inPType) {
print STDERR "valuepending -> 1\n" if ($valueDebug);
$parserState->{valuepending} = 1;
if ($parserState->{sodname}) {
$parserState->{preEqualsSymbol} = $parserState->{sodname};
} else {
$parserState->{preEqualsSymbol} = $parserState->{lastsymbol};
}
$parserState->{sodclass} = "variable";
print STDERR "sodclass -> variable (implicit)[10]\n" if ($sodDebug);
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [13]\n" if ($localDebug);
}; }; ($part =~ /,/o) && do {
print STDERR "COMMA: CASE 41\n" if ($liteDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
$parserState->{onlyComments} = 0;
print STDERR "[r]onlyComments -> 0\n" if ($macroDebug);
}
print STDERR "PPP AT COMMA: $parserState->{parsedParamParse}\n" if ($parseDebug || $localDebug || $parmDebug);
if ($part =~ /,/o && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
if (($parserState->{parsedParamParse} == 3 || $parserState->{parsedParamParse} == 4) && ((scalar(@braceStack)-$parserState->{initbsCount}-$parserState->{functionReturnsCallback}) == 1) && (peek(\@braceStack) eq '(' || peek(\@braceStack) eq '{')) {
print STDERR "$part is a comma\n" if ($localDebug || $parseDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) { push(@{$parserState->{parsedParamList}}, $parsedParam); }
print STDERR "pushed $parsedParam into parsedParamList [2]\n" if ($parmDebug);
$parsedParam = "";
$parserState->{parsedParamParse} = 4;
print STDERR "parsedParamParse -> 4[comma]\n" if ($parmDebug);
} elsif ($parserState->{parsedParamParse}) {
if ($parmDebug) {
warn "WARNING: PPP AT COMMA NOT 3 or 4 (or maybe in string, comment, etc.)!\n";
}
}
if ((!$parserState->{parsedParamParse}) && ($parserState->{sodclass} eq "variable" ||
$parserState->{sodclass} eq "constant" || $parserState->{sodclass} eq "") &&
($lang eq "C" || $lang eq "Csource" || $lang eq "java" || $lang eq "perl") && $parserState->{sodname} &&
(!(scalar(@braceStack)-$parserState->{initbsCount}))) {
print STDERR "PARSER STATE: $parserState\n" if ($parseDebug || $localDebug);
print STDERR "VARIABLE SODNAME ".$parserState->{sodname}."\n" if ($parseDebug || $localDebug);
print STDERR "VARIABLE RETURNTYPE \"".$parserState->{returntype}."\"\n" if ($parseDebug || $localDebug);
print STDERR "VARIABLE SODTYPE \"".$parserState->{sodtype}."\"\n" if ($parseDebug || $localDebug);
if ($parserState->{variablenames}) {
my $basetype = $parserState->{sodtype};
my $stars = $parserState->{curvarstars};
print STDERR "ADDED STARS: $stars\n" if ($parseDebug || $localDebug);
my %temp = %{$parserState->{variablenames}};
$parserState->{variablenames} = \%temp;
$temp{$parserState->{sodname}} = $parserState->{value};
my %tempb = %{$parserState->{variablestars}};
$parserState->{variablestars} = \%tempb;
$tempb{$parserState->{sodname}} = $stars;
$parserState->{curvarstars} = "";
} else {
my %temp = ();
my %tempb = ();
my $basetype = $parserState->{sodtype};
my $stars = "";
if ($basetype =~ s/(\**)\s*$//s) {
$stars = $1;
}
print STDERR "NEW SET STARS: $stars\n" if ($parseDebug || $localDebug);
$parserState->{variabletype} = $basetype;
$temp{$parserState->{sodname}} = $parserState->{value};
$tempb{$parserState->{sodname}} = $stars;
$parserState->{variablenames} = \%temp;
$parserState->{variablestars} = \%tempb;
$parserState->{curvarstars} = "";
}
$parserState->{bracePending} = 1;
}
}; }; ($part =~ /[*^]/) && do {
print STDERR "PUNCTUATION: CASE 41A\n" if ($liteDebug);
if ($part =~ /[*]/) { $parserState->{curvarstars} .= $part; }
if ($lastnspart eq "(" && !($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) &&
!$parserState->{callbackNamePending} &&
((scalar(@braceStack)-$parserState->{initbsCount}) == 1)) {
$parserState->{callbackNamePending} = 3;
}
}; {
print STDERR "DEFAULT CASE: CASE 42\n" if ($liteDebug);
print STDERR "DEFAULT CASE\n" if ($localDebug || $parseDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar})) {
my $tempavail = ignore($part, $ignoreref, $perheaderignoreref);
if ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) { $tempavail = 0; }
if ($parserState->{ignoreAvailabilityMacros}) { $tempavail = 0; }
if (!$tempavail) {
if ($part =~ /\S/o) {
$parserState->{onlyComments} = 0;
print STDERR "[s]onlyComments -> 0\n" if ($macroDebug);
}
if (!$continuation && !$occspace) {
$curline = spacefix($curline, $part, $lastchar);
} else {
$continuation = 0;
$occspace = 0;
}
if (length($part) && !($parserState->{inComment} || $parserState->{inInlineComment})) {
if ($localDebug && $lastchar eq ")") {print STDERR "LC: $lastchar\nPART: $part\n";}
if ($lastchar eq ")" && $parserState->{sodclass} eq "function" && ($lang eq "C" || $lang eq "Csource") && !(scalar(@braceStack)-$parserState->{initbsCount})) {
if ($part !~ /^\s*;/o) {
if (!isKeyword($part, $keywordhashref, $case_sensitive)) {
my $tempavail = ignore($part, $ignoreref, $perheaderignoreref);
if ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) { $tempavail = 0; }
if ($parserState->{ignoreAvailabilityMacros}) { $tempavail = 0; }
if (!$tempavail) {
print STDERR "K&R C FUNCTION FOUND [2].\n" if ($localDebug);
print STDERR "TOKEN: \"$part\"\n" if ($localDebug);
print STDERR "TA: \"$tempavail\"\n" if ($localDebug);
$parserState->{kr_c_function} = 1;
$parserState->{kr_c_name} = $parserState->{sodname};
$parserState->{parsedParamParse} = 1;
print STDERR "parsedParamParse -> 1[default1]\n" if ($parmDebug);
}
}
}
}
$lastchar = $part;
if ($part =~ /\w/o || $part eq "::") {
if ($parserState->{callbackNamePending} == 1) {
if (!($part eq $parseTokens{structname} || $part eq $parseTokens{enumname} || $part eq $parseTokens{unionname} || $part eq $parseTokens{typedefname})) {
print STDERR "callbackNamePending -> 2\n" if ($localDebug || $cbnDebug);
$parserState->{callbackNamePending} = 2;
}
} elsif ($parserState->{callbackNamePending} == 3) {
print STDERR "callbackNamePending -> 4\n" if ($localDebug || $cbnDebug);
$parserState->{callbackNamePending} = 4;
$parserState->{callbackName} = $part;
$parserState->{name} = "";
$parserState->{sodclass} = "";
print STDERR "sodclass -> \"\" (callback name pending)[11]\n" if ($sodDebug);
$parserState->{cbsodname} = $parserState->{sodname};
$parserState->{sodname} = "";
} elsif ($parserState->{callbackNamePending} == 4) {
if ($part eq "::") {
print STDERR "callbackNamePending -> 5\n" if ($localDebug || $cbnDebug);
$parserState->{callbackNamePending} = 5;
$parserState->{callbackName} .= $part;
} elsif ($part !~ /\s/o) {
print STDERR "callbackNamePending -> 0\n" if ($localDebug || $cbnDebug);
$parserState->{callbackNamePending} = 0;
}
} elsif ($parserState->{callbackNamePending} == 5) {
if ($part !~ /\s/o) {
print STDERR "callbackNamePending -> 4\n" if ($localDebug || $cbnDebug);
if ($part !~ /\*/ && $part !~ /\^/) {
$parserState->{callbackNamePending} = 4;
}
$parserState->{callbackName} .= $part;
}
}
if ($parserState->{namePending} == 2) {
$parserState->{namePending} = 1;
print STDERR "namePending -> 1 [4]\n" if ($parseDebug);
if (!(scalar(@braceStack)-$parserState->{initbsCount}) && ($parserState->{simpleTypedef} == 2)) {
print STDERR "bracePending -> 1\n" if ($localDebug);
$parserState->{bracePending} = 1;
}
} elsif ($parserState->{namePending}) {
if ($parserState->{name} eq "") { $parserState->{name} = $part; }
$parserState->{namePending} = 0;
print STDERR "namePending -> 0 [5]\n" if ($parseDebug);
} elsif ($parserState->{bracePending} == 1) {
if ($part eq "::") {
print STDERR "bracePending -> 2 [classmember]\n" if ($localDebug);
$parserState->{bracePending} = 2;
} else {
print STDERR "IT'S A VARIABLE! NAME WAS \"$part\".\n" if ($localDebug);
print STDERR "Word token before brace. Setting sodname to ".$parserState->{lastsymbol}."\n" if ($localDebug || $sodDebug);
$parserState->{sodname} = $part;
$parserState->{sodtype} = "$declaration$curline";
$parserState->{sodclass} = "variable";
print STDERR "sodclass -> variable (implicit)[12]\n" if ($sodDebug);
$parserState->{frozensodname} = $part;
print STDERR "bracePending -> 0 [word]\n" if ($localDebug);
$parserState->{bracePending} = 0;
}
} elsif ($parserState->{bracePending} == 2) {
$parserState->{bracePending}--;
}
} if ($part !~ /[][,;\n\r]/o && !$parserState->{inBrackets}) {
my $opttilde = "";
if ($parserState->{seenTilde}) { $opttilde = "~"; }
if ($parserState->{sodbrackets}) {
print STDERR "SODNAME: $parserState->{sodname} SODTYPE: $parserState->{sodtype}\n" if ($sodDebug);
$parserState->{sodname} .= $parserState->{sodbrackets};
$parserState->{sodbrackets} = "";
print STDERR "sodbrackets appended and cleared\n" if ($sodDebug);
}
print STDERR "CHECKPOINT: INTEMPLATE IS ".$parserState->{inTemplate}." SOD IS ".$parserState->{startOfDec}."\n" if ($localDebug || $sodDebug);
if ($parserState->{startOfDec} == 1) { if (!$parserState->{inTemplate}) {
if (!length($accessregexp) || ($part !~ /$accessregexp/)) {
if (!isKeyword($part, $keywordhashref, $case_sensitive)) {
print STDERR "Setting sodname (maybe type) to \"$part\"\n" if ($sodDebug);
$parserState->{sodname} = $opttilde.$part;
if ($part =~ /\w/o) {
$parserState->{startOfDec}++;
}
} else {
$parserState->{sodtype} = " ".$opttilde.$part;
$parserState->{startOfDec}++;
}
} else {
print STDERR "Not adjusting startOfDec or sodname because in access (e.g. public/private/*).\n" if ($localDebug || $sodDebug);
}
} else {
print STDERR "Not adjusting startOfDec or sodname because in template.\n" if ($localDebug || $sodDebug);
}
} elsif ($parserState->{startOfDec} == 2) {
if ($part =~ /\w/o && !$parserState->{inTemplate}) {
$parserState->{preTemplateSymbol} = "";
}
if (!$parserState->{inTemplate} && !$parserState->{waitingForExceptions}) {
if (isKeyword($part, $keywordhashref, $case_sensitive)) {
print STDERR "ISKEYWORD: $part. Setting prekeywordsodname to ".$parserState->{sodname}."\n" if ($sodDebug || $parseDebug || $localDebug);
print STDERR "ISKEYWORD: $part. Setting prekeywordsodtype to ".$parserState->{sodtype}."\n" if ($sodDebug || $parseDebug || $localDebug);
$parserState->{prekeywordsodname} = $parserState->{sodname};
$parserState->{prekeywordsodtype} = $parserState->{sodtype};
} else {
$parserState->{prekeywordsodname} = "";
$parserState->{prekeywordsodtype} = "";
}
if ($parserState->{inOperator} == 1) {
$parserState->{sodname} .= $part;
} else {
if ($parserState->{variableNameConcat}) {
$parserState->{sodname} .= $opttilde.$part;
$parserState->{variableNameConcat}--;
} else {
if (length($parserState->{sodname})) {
my $spc = "";
if ($parserState->{sodname} !~ /[][()]/) { $spc = " "; }
$parserState->{sodtype} .= "$spc$parserState->{sodname}";
}
$parserState->{sodname} = $opttilde.$part;
}
}
print STDERR "sodname set to $part\n" if ($sodDebug);
} else {
print STDERR "Not adjusting startOfDec or sodname because in template.\n" if ($localDebug || $sodDebug);
}
} else {
$parserState->{startOfDec} = 0;
print STDERR "startOfDec -> 0 [14]\n" if ($localDebug);
}
} elsif ($part eq "[") { $parserState->{inBrackets} += 1;
print STDERR "inBrackets -> $parserState->{inBrackets}\n" if ($sodDebug);
print STDERR "SOD AT BRACKET: ".$parserState->{startOfDec}."\n" if ($sodDebug);
} elsif ($part eq "]") {
$parserState->{inBrackets} -= 1;
print STDERR "inBrackets -> $parserState->{inBrackets}\n" if ($sodDebug);
} if (!($part eq $parseTokens{eoc})) {
print STDERR "SETTING LS ($part)\n" if ($parseDebug);
if ($parserState->{lastsymbol} =~ /\,\s*$/o) {
$parserState->{lastsymbol} .= $part;
} elsif ($parserState->{inTypedef} && !(scalar(@braceStack)-$parserState->{initbsCount}) && $part =~ /,/) {
$parserState->{lastsymbol} .= $part;
} elsif ($part =~ /^\s*\;\s*$/o) {
$parserState->{lastsymbol} .= $part;
} elsif (length($part)) {
$parserState->{lastsymbol} = $part;
}
} } }
} } }
if ($part =~ /\S/ && $part ne ";" && $part ne ";;" && $parserState->{afterSemi}) {
$parserState->{afterSemi} = 0;
}
print STDERR "INMACRO: ".$parserState->{inMacro}." AT TOKEN $part\n" if ($cppDebug);
if ($parserState->{inMacro} == 3 && !$parserState->{seenMacroStart}) {
if ($part =~ /\S/) {
print STDERR "seenMacroStart -> 1 at token $part\n" if ($cppDebug);
$parserState->{seenMacroStart} = 1;
}
} elsif ($parserState->{inMacro} == 3 && !$parserState->{seenMacroName}) {
if ($part =~ /\S/) {
print STDERR "PARSER seenMacroName -> 1 at token $part\n" if ($cppDebug);
$parserState->{seenMacroName} = 1;
}
} elsif ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) {
print STDERR "PARSER inMacroTail -> 1 at token $part\n" if ($cppDebug);
$parserState->{inMacroTail} = 1;
}
if (($part =~ /\S/ && $part ne "<<") && ($parserState->{inRuby} == 3) && $parserState->{inRubyBlock} eq "") {
$parserState->{inRubyBlock} = $part;
}
if ($parserState->{occmethod} && $parserState->{gatheringObjCReturnType} == 1) {
$parserState->{gatheringObjCReturnType} = 2;
} elsif ($parserState->{occmethod} && $parserState->{gatheringObjCReturnType} == 2) {
$parserState->{occmethodreturntype} .= $part;
}
if ($parserState->{waitingForTypeInformation} == 1 && $part !~ /\s/) {
$parserState->{waitingForTypeInformation} = -1;
} elsif ($parserState->{waitingForTypeInformation} == 2) {
$parserState->{waitingForTypeInformation} = 1;
}
if ($inRegexpCharClass > 1 && $inRegexpCharClass != 4) {
$inRegexpCharClass--;
}
if (($parserState->{seenBraces} || $trailingHide) && !$HeaderDoc::includeFunctionContents && ($parserState->{INIF} != 1)) {
if ($treepart) {
print STDERR "ADDED \"$treepart\" to function contents\n" if ($functionContentsDebug);
$parserState->{functionContents} .= $treepart;
} else {
print STDERR "ADDED \"$part\" to function contents\n" if ($functionContentsDebug);
$parserState->{functionContents} .= $part;
}
} elsif (($parserState->{seenBraces} || $trailingHide) && !$HeaderDoc::includeFunctionContents) {
print STDERR "NOT ADDING \"$part\" to function contents (INIF: ".$parserState->{INIF}." TEMPINIF: $tempInIf\n" if ($functionContentsDebug);
} else {
print STDERR "NOT ADDING \"$part\" to function contents (!seenBraces)\n" if ($functionContentsDebug);
}
if ($part !~ /\\/o) {
if (!($parserState->{inMacro} || $parserState->{inMacroLine}) || $part !~ /\s/) {
$parserState->resetBackslash();
}
}
if (length($part)) { $lasttoken = $part; }
if (length($part) && $inRegexpTrailer) { --$inRegexpTrailer; }
if ($postPossNL) { --$postPossNL; }
if (($parserState->{simpleTypedef} == 1) && ($part ne $parseTokens{typedefname}) &&
!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} ||
$inRegexp)) {
$parserState->{simpleTDcontents} .= $part;
}
my $ignoretoken = ignore($part, $ignoreref, $perheaderignoreref);
if ($parserState->{inMacro} == 3 && !$parserState->{inMacroTail}) { $ignoretoken = 0; }
if ($parserState->{ignoreAvailabilityMacros}) { $ignoretoken = 0; }
my $hide = ( $hideTokenAndMaybeContents ||
( $ignoretoken &&
!( $parserState->{inString} || $parserState->{inComment} ||
$parserState->{inInlineComment} || $parserState->{inChar}
)
)
);
print STDERR "TPONL: $treePopOnNewLine TPTWO: ".$parserState->{treePopTwo}."\n" if ($tsDebug);
print STDERR "TN: $treeNest TS: $treeSkip nTS: ".scalar(@treeStack)."\n" if ($tsDebug || $parserStateInsertDebug);
print STDERR "sethollow: $sethollow\n" if ($parserStateInsertDebug);
if (!$treeSkip) {
if ($HeaderDoc::includeFunctionContents || !($parserState->{seenBraces} || $trailingHide)) { if ($treeNest != 2) {
if (length($treepart)) {
if ((($parserState->{inComment} == 1) || ($parserState->{inInlineComment} == 1)) && $treepart !~ /[\r\n!]/) {
$treeCur->token($treeCur->token() . $treepart);
} else {
$treeCur = $treeCur->addSibling($treepart, $hide);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
}
$treepart = "";
} else {
if ((($parserState->{inComment} == 1) || ($parserState->{inInlineComment} == 1)) && $treepart !~ /[\r\n!]/) {
$treeCur->token($treeCur->token() . $part);
} else {
$treeCur = $treeCur->addSibling($part, $hide);
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
}
}
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($treeNest) {
if ($sethollow) {
print STDERR "WILL INSERT STATE $parserState (SETHOLLOW) at ".$treeCur->token()."\n" if ($parserStackDebug);
$parserState->setHollowWithLineNumbers($treeCur, $fileoffset, $inputCounter);
$sethollow = 0;
}
print STDERR "TSPUSH\n" if ($tsDebug || $treeDebug);
push(@treeStack, $treeCur);
$treeCur = $treeCur->addChild("", 0);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
} else {
print STDERR "Not adding sibling (seenBraces)\n" if ($treeDebug);
}
if ($setIsAvailable) {
$treeCur->isAvailabilityMacro(1);
}
if ($parserState->{inComment} > 1) { $parserState->{inComment}--; }
if ($parserState->{inInlineComment} > 1) { $parserState->{inInlineComment}--; }
if (($parserState->{inComment} == 1) && $treepart eq "!") {
$parserState->{inComment} = 3;
}
if (($parserState->{inInlineComment} == 1) && $treepart eq "!") {
$parserState->{inInlineComment} = 3;
}
$treeNest = 0;
if ($treeDebug) { print STDERR "TS TREENEST -> 0 [19]\n"; }
if (!$parserState->{freezereturn} && $parserState->{hollow} && !$parserState->{inComment} && !$parserState->{leavingComment}) {
$parserState->{returntype} = "$declaration$curline";
print STDERR "APPENDING TO RETURNTYPE[2]: NOW \"$parserState->{returntype}\".\n" if ($retDebug);
} elsif (!$parserState->{freezereturn} && !$parserState->{hollow} && !$parserState->{inComment} && !$parserState->{leavingComment}) {
$parserState->{returntype} = "$curline";
print STDERR "REPLACING RETURNTYPE[2]: NOW \"$parserState->{returntype}\".\n" if ($retDebug);
$declaration = "";
}
if ($pascal && $parserState->{waitingForTypeInformation}) {
print STDERR "PASCAL END CASE RT: $parserState->{returntype}\nCL: $curline\n" if ($parseDebug || $localDebug || $retDebug);
$parserState->{returntype} = $curline;
print STDERR "REPLACING RETURNTYPE[3]: NOW \"$parserState->{returntype}\".\n" if ($retDebug);
}
print STDERR "AT MIDPOINT, TREECUR IS $treeCur (".$treeCur->token().")\n" if ($localDebug || $parserStateInsertDebug);
print STDERR "TOKEN $part parsedParamParse going into end is $parserState->{parsedParamParse}\n" if ($parmDebug);
if (($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) ||
!$ignoretoken) {
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar}) &&
!$ppSkipOneToken) {
if ($parserState->{parsedParamParse} == 1 || $parserState->{parsedParamParse} == 3 ||
$parserState->{parsedParamParse} == 5) {
$parsedParam .= $part;
print STDERR "PARSED PARAM IS NOW $parsedParam\n" if ($parmDebug);
} elsif ($parserState->{parsedParamParse} == 2 || $parserState->{parsedParamParse} == 4 ||
$parserState->{parsedParamParse} == 6) {
$parserState->{parsedParamParse}--;
print STDERR "parsedParamParse -> $parserState->{parsedParamParse}"."[endgame]\n" if ($parmDebug);
}
}
if ($ppSkipOneToken) {
$hollowskip = $ppSkipOneToken;
print STDERR "hollowskip -> $ppSkipOneToken (ppSkipOneToken)\n" if ($parserStateInsertDebug);
}
$ppSkipOneToken = 0;
print STDERR "MIDPOINT CL: $curline\nDEC:$declaration\nSCR: \"$scratch\"\n" if ($localDebug);
if ($HeaderDoc::includeFunctionContents || !($parserState->{seenBraces} || $trailingHide)) {
if ($parserState->{inString}) {
$curstring .= $part;
} else {
if (length($curstring)) {
if (length($curline) + length($curstring) >
$HeaderDoc::maxDecLen) {
$scratch = nspaces($prespace);
if ($curline !~ /^\s*\n/so) { $curline =~ s/^\s*//sgo; }
print STDERR "CURLINE CLEAR [1]\n" if ($localDebug);
$declaration .= "$scratch$curline\n";
$curline = "";
$prespace += $prespaceadjust;
$prespaceadjust = 0;
$prespaceadjust -= 4;
$prespace += 4;
} else {
if ($lastchar =~ /\=$/o) {
$curline .= " ";
}
}
$curline .= $curstring;
$curstring = "";
}
if ((length($curline) + length($part) > $HeaderDoc::maxDecLen)) {
$scratch = nspaces($prespace);
if ($curline !~ /^\s*\n/so) { $curline =~ s/^\s*//sgo; }
$declaration .= "$scratch$curline\n";
print STDERR "CURLINE CLEAR [2]\n" if ($localDebug);
$curline = "";
$prespace += $prespaceadjust;
$prespaceadjust = 0;
$prespaceadjust -= 4;
$prespace += 4;
}
if (length($curline) || $part ne " ") {
$curline .= $part;
}
}
if (peek(\@braceStack) ne "<") {
if ($part =~ /\n/o || ($part =~ /[\(;,]/o && $nextpart !~ /\n/o &&
!$parserState->{occmethod}) ||
($part =~ /[:;.]/o && $nextpart !~ /\n/o &&
$parserState->{occmethod})) {
if ($curline !~ /\n/o && !($parserState->{inMacro} || ($pascal && (scalar(@braceStack)-$parserState->{initbsCount})) || $parserState->{inInlineComment} || $parserState->{inComment} || $parserState->{inString})) {
$curline .= "\n";
}
$scratch = nspaces($prespace);
if ($curline !~ /\n/o) { $curline =~ s/^\s*//go; }
if ($declaration !~ /\n\s*$/o) {
$scratch = " ";
if ($localDebug) {
my $zDec = $declaration;
$zDec = s/ /z/sg;
$zDec = s/\t/Z/sg;
print STDERR "ZEROSCRATCH\n";
print STDERR "zDec: \"$zDec\"\n";
}
}
$declaration .= "$scratch$curline";
print STDERR "CURLINE CLEAR [3]\n" if ($localDebug);
$curline = "";
print STDERR "PS: $prespace -> " . $prespace + $prespaceadjust . "\n" if ($localDebug);
$prespace += $prespaceadjust;
$prespaceadjust = 0;
} elsif ($part =~ /[\(;,]/o && $nextpart !~ /\n/o &&
($parserState->{occmethod} == 1)) {
print STDERR "SPC\n" if ($localDebug);
$curline .= " "; $occspace = 1;
} else {
print STDERR "NOSPC: $part:$nextpart:$parserState->{occmethod}\n" if ($localDebug);
}
}
}
if ($parserState->{temponlyComments}) {
$parserState->{onlyComments} = $parserState->{temponlyComments};
$parserState->{temponlyComments} = undef;
}
print STDERR "CURLINE IS \"$curline\".\n" if ($localDebug);
my $bsCount = scalar(@braceStack);
print STDERR "ENDTEST: $bsCount \"$parserState->{lastsymbol}\"\n" if ($localDebug || $continueDebug);
print STDERR "KRC: $parserState->{kr_c_function} SB: $parserState->{seenBraces}\n" if ($localDebug || $continueDebug);
print STDERR "DEANL: ".$parserState->{declarationEndsAtNewLine}." PART: \"$treepart\"\n" if ($parseDebug || $asDebug || $continueDebug);
if (!($bsCount - $parserState->{initbsCount}) && ($parserState->{lastsymbol} =~ /;\s*$/o || ($parserState->{declarationEndsAtNewLine} && $partIsNL))) {
if ($parserState->{declarationEndsAtNewLine} && $partIsNL) {
print STDERR "CREATING NEW PARSER STATE NOW.\n" if ($parseDebug || $asDebug);
$parserState->{declarationEndsAtNewLine} = 0;
}
if ((!$parserState->{kr_c_function} || $parserState->{seenBraces}) && !$parserState->{inMacro}) {
print STDERR "DPB\n" if ($parserStateInsertDebug || $continueDebug);
if (!scalar(@parserStack)) {
$continue = 0;
print STDERR "CONTINUE -> 0 [3]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
} elsif (!$parserState->{onlyComments}) {
if ($parserState->{noInsert}) {
print STDERR "parserState insertion skipped[SEMI-1]\n" if ($parserStateInsertDebug);
} elsif ($parserState->{hollow}) {
my $treeRef = $parserState->{hollow};
print STDERR "inserted parser state into tree [semi]\n" if ($parserStateInsertDebug);
print STDERR "Last tree node set to $treeCur [7]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$treeRef->addRawParsedParams(\@{$parserState->{parsedParamList}});
$treeRef->parserState($parserState);
} elsif ($parserState->{classtype} && length($parserState->{classtype})) {
warn "Couldn't insert info into parse tree[3class].\n" if ($localDebug);
} else {
warn "Couldn't insert info into parse tree[3].\n";
print STDERR "Printing tree.\n";
$parserState->print();
$treeTop->dbprint();
}
print STDERR "parserState: Created parser state[2].\n" if ($parserStackDebug);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
print STDERR "NEWRETURNTYPE: $parserState->{returntype}\n" if ($localDebug);
print STDERR "CURLINE CLEAR[PRS2]\n" if ($localDebug);
$curline = "";
} else {
print STDERR "parserState insertion skipped[ONLY COMMENTS]\n" if ($parserStateInsertDebug);
}
}
} else {
print STDERR "bsCount: $bsCount - $parserState->{initbsCount}, ls: $parserState->{lastsymbol}\n" if ($localDebug);
pbs(@braceStack);
}
if (!($bsCount - $parserState->{initbsCount}) && ($parserState->{seenBraces} || $trailingHide) && ($parserState->{sodclass} eq "function" || $parserState->{inOperator}) &&
($nextpart ne ";")) {
if ($parserState->{treePopTwo} || $ruby || $parseTokens{functionisbrace}) {
while ($parserState->{treePopTwo}--) {
$treeCur = pop(@treeStack) || $treeTop;
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
$treeCur = $treeCur->lastSibling();
$treeCur->parsedParamCopy(\@{$parserState->{parsedParamList}}, $lang, $sublang);
print STDERR "TSPOP [13]: now $treeCur\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($ruby || $parseTokens{functionisbrace}) {
$treeCur = $treeCur->addSibling("", 0);
} else {
$treeCur = $treeCur->addSibling(";", 0);
}
if ($HeaderDoc::includeFunctionContents && $reMark) {
$treeCur->{RE_STATE} = $reMark;
}
print STDERR "parser state lastTreeNode reset [treePopTwo]\n" if ($parserStateInsertDebug);
print STDERR "Last tree node set to $treeCur [8]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$parserState->{treePopTwo} = 0;
}
print STDERR "CHECKINIF: ".$parserState->{INIF}."\n" if ($continueDebug);
if (!scalar(@parserStack) && !$parserState->{INIF} && !$tempInIf) {
$continue = 0;
print STDERR "CONTINUE -> 0 [4]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
} elsif ($parserState->{inrbraceargument}) {
print STDERR "parserState insertion skipped[inrbraceargument]\n" if ($parserStackDebug);
} elsif (!$parserState->{onlyComments} && !$parserState->{INIF} && !$tempInIf) {
if ($parserState->{noInsert}) {
print STDERR "parserState insertion skipped[SEMI-2]\n" if ($parserStackDebug);
} elsif ($parserState->{hollow}) {
my $treeRef = $parserState->{hollow};
print STDERR "inserted parser state into tree [rbrace]\nEOD: $treeCur\n" if ($parserStateInsertDebug);
print STDERR "Last tree node set to $treeCur [9] (token: \"".$treeCur->token()."\")\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$treeRef->addRawParsedParams(\@{$parserState->{parsedParamList}});
$treeRef->parserState($parserState);
} else {
warn "Couldn't insert info into parse tree[4].\n";
}
print STDERR "parserState: Created parser state[3].\n" if ($parserStackDebug);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
print STDERR "CURLINE CLEAR[PRS3]\n" if ($localDebug);
$curline = "";
}
}
print STDERR "INMACRO: ".$parserState->{inMacro}."\n" if ($localDebug || $cppDebug || $cppDebug);
print STDERR "IM: ".$parserState->{inMacro}." IQ: ".$parserState->isQuoted($lang, $sublang)."\n" if ($localDebug);
if (($parserState->{inMacro} == 3 && !$parserState->isQuoted($lang, $sublang)) || $parserState->{inMacro} == 4) {
print STDERR "CHECKPART \"$part\" AGAINST NEWLINE\n" if ($localDebug || $cppDebug);
if ($part =~ /[\n\r]/o && !$parserState->{inComment}) {
print STDERR "MLS: $parserState->{lastsymbol}\n" if ($macroDebug);
print STDERR "PARSER STACK CONTAINS ".scalar(@parserStack)." FRAMES\n" if ($cppDebug || $parserStackDebug);
if (!scalar(@parserStack)) {
$continue = 0;
print STDERR "CONTINUE -> 0 [5]\n" if ($parseDebug || $cppDebug || $macroDebug || $localDebug || $continueDebug);
} elsif (!$parserState->{onlyComments}) {
print STDERR "NOT setting continue to 0 for macro: parser stack nonempty\n" if ($liteDebug);
print STDERR "DONE WITH MACRO. HANDLING.\n" if ($localDebug || $parseDebug);
if ($parserState->{inMacro} == 3) {
if (!$HeaderDoc::skipNextPDefine) {
cpp_add($parserState->{hollow}, 0, $lang, $sublang);
} else {
cpp_add($parserState->{hollow}, 1, $lang, $sublang);
$HeaderDoc::skipNextPDefine = 0;
}
}
if ($parserState->{noInsert}) {
print STDERR "parserState insertion skipped\n" if ($parserStackDebug);
} elsif ($parserState->{hollow}) {
my $treeRef = $parserState->{hollow};
print STDERR "inserted parser state into tree [macro]\n" if ($parserStateInsertDebug);
print STDERR "Last tree node set to $treeCur [10]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$treeRef->addRawParsedParams(\@{$parserState->{parsedParamList}});
$treeRef->parserState($parserState);
} else {
warn "Couldn't insert info into parse tree[5].\n";
}
print STDERR "parserState: Created parser state[4].\n" if ($parserStackDebug);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
print STDERR "CURLINE CLEAR[PRS4]\n" if ($localDebug);
$curline = "";
}
}
} elsif ($parserState->{inMacro} == 2) {
my $linenum = $inputCounter + $fileoffset;
warn "$fullpath:$linenum: warning: Declaration starts with # but is not preprocessor macro\n";
warn "PART: $part\n";
} elsif ($parserState->{inMacro} == 3 && $parserState->isQuoted($lang, $sublang)) {
print STDERR "TAIL BACKSLASH ($continue)\n" if ($localDebug || $macroDebug);
}
if ($parserState->{valuepending} == 2) {
$parserState->{value} .= $part;
} elsif ($parserState->{valuepending}) {
$parserState->{valuepending} = 2;
print STDERR "valuepending -> 2\n" if ($valueDebug);
}
}
print STDERR "OOGABOOGA\n" if ($parserStackDebug);
if ($pushParserStateAfterToken == 1) {
if ($parserState->{inClass}) { configureAccessControlStateForClass($parserState); }
print STDERR "parserState pushed onto stack[token]\n" if ($parserStackDebug);
print STDERR "Last tree node set to $treeCur [11]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
if ($lang eq "applescript") {
$parserState->{lastDisplayNode} = $treeCur;
$treeTop->{lastDisplayNode} = $treeCur;
}
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
$pushParserStateAfterToken = 0;
$pushParserStateAtBrace = 0;
} elsif ($pushParserStateAfterWordToken == 1) {
if ($part =~ /\w/) {
print STDERR "parserState pushed onto stack[word]\n" if ($parserStackDebug);
print STDERR "Last tree node set to $treeCur [12]\n" if ($parserStateInsertDebug);
if ($parserState->{inClass}) { configureAccessControlStateForClass($parserState); }
$parserState->{lastTreeNode} = $treeCur;
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
$pushParserStateAfterWordToken = 0;
}
} elsif ($pushParserStateAfterWordToken) {
print STDERR "PPSAFTERWT CHANGED $pushParserStateAfterWordToken -> " if ($parserStackDebug);
$pushParserStateAfterWordToken--;
print STDERR "$pushParserStateAfterWordToken\n" if ($parserStackDebug);
} elsif ($pushParserStateAtBrace) {
print STDERR "PPSatBrace?\n" if ($parserStackDebug);
print STDERR "check: ".$parserState->isLeftBrace($part, $lang, \%parseTokens, $case_sensitive, scalar(@braceStack))."\n" if ($rubyDebug || $parseDebug || $HeaderDoc::AppleScriptDebug);
if ($parserState->isLeftBrace($part, $lang, \%parseTokens, $case_sensitive, scalar(@braceStack))) {
if ($part =~ /[\n\r]/) { $parserState->{inRubyClass} = 2; }
$parserState->{ISFORWARDDECLARATION} = 0;
if ($parserState->{inClass}) { configureAccessControlStateForClass($parserState); }
print STDERR "parserState pushed onto stack[brace]\n" if ($parserStackDebug);
print STDERR "Last tree node set to $treeCur [13]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$curline = "";
$parserState->{storeDec} = $declaration;
$parserState->{freezereturn} = 1;
$declaration = "";
push(@parserStack, $parserState);
$parserState = HeaderDoc::ParserState->new( "FULLPATH" => $fullpath, "lang" => $lang, "sublang" => $sublang );
$parserState->{skiptoken} = 1;
$parserState->{inputCounter} = $inputCounter;
$parserState->{initbsCount} = scalar(@braceStack);
$parserState->{noInsert} = $setNoInsert;
$setNoInsert = 0;
$pushParserStateAtBrace = 0;
} elsif ($pushParserStateAtBrace) {
if ($part =~ /\;/) {
$pushParserStateAtBrace = 0;
$parserState->{inClass} = 0;
print STDERR "inClass -> 0 [10]\n" if ($classDebug);
}
}
if (!$parserState->{hollow}) {
my $tok = $part; print STDERR "parserState: NOT HOLLOW [1]\n" if ($parserStackDebug);
print STDERR "IS: $parserState->{inString}\nICom: $parserState->{inComment}\nISLC: $parserState->{inInlineComment}\nIChar: $parserState->{inChar}\nSkipToken: $parserState->{skiptoken}\nHollowSkip: $hollowskip\n" if ($parserStackDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{skiptoken} || $hollowskip)) {
print STDERR "parserState: NOT STRING/CHAR/COMMENT\n" if ($parserStackDebug);
if ($tok =~ /\S/) {
print STDERR "parserState: PS IS $parserState\n" if ($parserStackDebug);
print STDERR "parserState: NOT WHITESPACE : ".$parserState->{hollow}." -> $treeCur\n" if ($parserStackDebug);
if (!$parserState->isRightBrace($tok, $lang, \%parseTokens, $case_sensitive) && $part !~ /\)/) {
$parserState->setHollowWithLineNumbers($treeCur, $fileoffset, $inputCounter);
print STDERR "parserState: WILL INSERT STATE $parserState (HOLLOW-AUTO-1) AT TOKEN \"$part\"/\"".$treeCur->token()."\"\n" if ($parserStackDebug);
}
}
}
$hollowskip = 0;
print STDERR "hollowskip -> 0 (NOTHOLLOW - 1)\n" if ($parserStateInsertDebug);
$parserState->{skiptoken} = 0;
}
} else {
if (!$parserState->{hollow}) {
my $tok = $part; print STDERR "parserState: NOT HOLLOW [2]\n" if ($parserStackDebug);
print STDERR "IS: $parserState->{inString}\nICom: $parserState->{inComment}\nISLC: $parserState->{inInlineComment}\nIChar: $parserState->{inChar}\nSkipToken: $parserState->{skiptoken}\nHollowSkip: $hollowskip\n" if ($parserStackDebug);
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{skiptoken} || $hollowskip)) {
print STDERR "parserState: NOT STRING/CHAR/COMMENT\n" if ($parserStackDebug);
if ($tok =~ /\S/) {
print STDERR "parserState: PS IS $parserState\n" if ($parserStackDebug);
print STDERR "parserState: NOT WHITESPACE : ".$parserState->{hollow}." -> $treeCur\n" if ($parserStackDebug);
if (!$parserState->isRightBrace($tok, $lang, \%parseTokens, $case_sensitive) && $part !~ /\)/) {
$parserState->setHollowWithLineNumbers($treeCur, $fileoffset, $inputCounter);
print STDERR "parserState: WILL INSERT STATE $parserState (HOLLOW-AUTO-2) AT TOKEN \"$part\"/\"".$treeCur->token()."\"\n" if ($parserStackDebug);
}
}
}
$hollowskip = 0;
print STDERR "hollowskip -> 0 (NOTHOLLOW - 2)\n" if ($parserStateInsertDebug);
$parserState->{skiptoken} = 0;
}
}
if ($part =~ /\w+/) {
if (!($parserState->{inString} || $parserState->{inComment} || $parserState->{inInlineComment} || $parserState->{inChar} || $parserState->{skiptoken} || $hollowskip)) {
if ($parserState->{occparmlabelfound} == -2) {
if (!($parserState->{initbsCount} - scalar(@braceStack) )) { $parserState->{occparmlabelfound} = 0; if ($HeaderDoc::useParmNameForUnlabeledParms) {
$parserState->{occmethodname} .= "$part:";
} else {
$parserState->{occmethodname} .= ":";
}
if ($occMethodNameDebug) {
print STDERR "OCC parameter name substituted; OCC method name now ".$parserState->{occmethodname}." (lastsymbol was \"".$parserState->{lastsymbol}."\", part was \"".$part."\").\n";
}
}
} else {
if (!($parserState->{initbsCount} - scalar(@braceStack) )) { $parserState->{occparmlabelfound}++;
if ($occMethodNameDebug && ($parserState->{occparmlabelfound} > 0)) {
print STDERR "OCC possible label: \"$part\".\n";
}
}
}
}
}
if (length($part) && $part =~ /\S/o) { $lastnspart = $part; }
if ($parserState->{seenTilde} && length($part) && $part !~ /\s/o) { $parserState->{seenTilde}--; }
$part = $nextpart;
if ($parserState->{leavingComment}) {
$parserState->{leavingComment} = 0;
}
if ($parserState->{inMacro} > 1 && !$bshandled) {
if ($part !~ /[ \t]/) {
print STDERR "BS RESET\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);
$parserState->resetBackslash();
print STDERR "ISQUOTED NOW: ".$parserState->isQuoted($lang, $sublang)."\n" if ($parseDebug || $localDebug || $cppDebug || $macroDebug);;
}
};
if ($parserState->{rollbackPending}) {
$curline = $parserState->{preExternCcurline};
$declaration = $parserState->{preExternCdeclaration};
$parserState->rollback();
}
} if ($HeaderDoc::inputCounterDebug) {
print STDERR "continue: $continue IC: $inputCounter NLINES: $nlines\n";
}
}
if ($continue_no_return) {
return blockParse($fullpath, $fileoffset, $inputLinesRef, $inputCounter, $argparse, $ignoreref,
$perheaderignoreref, $perheaderignorefuncmacrosref, $keywordhashref, $case_sensitive, $lang, $sublang);
}
print STDERR "RETURNING DECLARATION\n" if ($localDebug);
if ($curline !~ /\n/) { $curline =~ s/^\s*//go; }
if ($curline =~ /\S/o) {
$scratch = nspaces($prespace);
$declaration .= "$scratch$curline\n";
}
print STDERR "($parserState->{typestring}, $parserState->{basetype})\n" if ($localDebug || $listDebug);
print STDERR "LS: $parserState->{lastsymbol}\n" if ($localDebug);
print STDERR "Last tree node set to $treeCur [14]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$parserState->{inputCounter} = $inputCounter;
print STDERR "PARSERSTATE: $parserState\n" if ($localDebug);
if ($parserState->{inMacro} == 3) {
if (!$HeaderDoc::skipNextPDefine) {
cpp_add($treeTop, 0, $lang, $sublang);
} else {
cpp_add($treeTop, 1, $lang, $sublang);
$HeaderDoc::skipNextPDefine = 0;
}
}
print STDERR "LEFTBPMAIN\n" if ($localDebug || $hangDebug);
if ($argparse && $apwarn) {
print STDERR "end argparse\n";
}
my $tempParserState = pop(@parserStack);
$declaration = $parserState->{storeDec}.$declaration;
while ($tempParserState) {
$parserState = $tempParserState;
print STDERR "Last tree node set to $treeCur [15]\n" if ($parserStateInsertDebug);
$parserState->{lastTreeNode} = $treeCur;
$parserState->{inputCounter} = $inputCounter;
$tempParserState = pop(@parserStack);
$declaration = $parserState->{storeDec}.$declaration;
}
if ($localDebug || $apDebug || $liteDebug || $parseDebug || $hangDebug) {
print STDERR "LEAVING BLOCKPARSE\n";
}
if (0) {
print STDERR "Returning the following parse tree:\n";
$treeTop->dbprint();
print STDERR "End of parse tree.\n";
}
return blockParseReturnState($parserState, $treeTop, $argparse, $declaration, $inPrivateParamTypes, $publicDeclaration, $lastACS, $retDebug, $fileoffset, 0, $parseTokens{definename}, $inputCounter, $lang, $sublang);
}
sub blockParseReturnState
{
my $parserState = shift;
my $treeTop = shift;
my $argparse = shift;
my $declaration = shift; my $inPrivateParamTypes = shift; my $publicDeclaration = shift; my $lastACS = shift; my $forcedebug = shift; my $fileoffset = shift; my $subparse = shift;
my $definename = shift;
my $inputCounter = shift;
my $lang = shift;
my $sublang = shift;
my $fullpath = $parserState->{FULLPATH};
my $nameObjDumpDebug = 0;
if ($forcedebug) { $treeTop->dbprint(); }
$forcedebug = $forcedebug || $HeaderDoc::fileDebug;
my $subparseDebug = 0;
my $localDebug = 0 || $forcedebug;
my $sodDebug = 0 || $forcedebug;
my $parseDebug = 0 || $forcedebug;
my $listDebug = 0 || $forcedebug;
my $parmDebug = 0 || $forcedebug;
my $retDebug = 0 || $forcedebug;
if (!length($declaration)) {
$declaration = $treeTop->textTree();
}
my $perlClassPrefix = "";
if ($parserState->{perlClassName}) {
$perlClassPrefix = $parserState->{perlClassName};
}
cluck("PARSERSTATE IS $parserState\n") if ($localDebug);
if ($forcedebug) { $parserState->print(); }
if ($forcedebug) { print STDERR "FD\n"; }
my $pascal = 0;
if ($lang eq "pascal") { $pascal = 1; }
my $perl_or_shell = 0;
if ($lang eq "perl" || $lang eq "shell") {
$perl_or_shell = 1;
}
if ($parserState->{seenElse} && $parserState->{functionContents} && !$parserState->{elseContents}) {
$parserState->{elseContents} = $parserState->{functionContents};
$parserState->{functionContents} = "";
} elsif ($parserState->{seenIf} && $parserState->{functionContents} && !$parserState->{ifContents}) {
$parserState->{ifContents} = $parserState->{functionContents};
$parserState->{functionContents} = "";
}
my $returntype = $parserState->{returntype};
my $sodtype = $parserState->{sodtype};
my $sodname = $perlClassPrefix.$parserState->{sodname};
my $basetype = $parserState->{basetype};
my $callbackName = $parserState->{callbackName};
my $psName = $parserState->{name};
my $posstypes = $parserState->{posstypes};
my $sodclass = $parserState->{sodclass};
my $value = $parserState->{value};
my $simpleTDcontents = $parserState->{simpleTDcontents};
my $availability = $parserState->{availability};
if ($parserState->{variabletype}) {
$returntype = $parserState->{variabletype};
$sodtype = $parserState->{variabletype};
}
if ($lang eq "tcl" && $parserState->{inClass}) {
$sodclass = "class";
$parserState->{sodclass} = "class";
$sodtype = join(",", @{$parserState->{pplStack}});
$parserState->{classtype} = "class";
print "SETTING sodtype TO $sodtype\n" if ($forcedebug);
}
if ($lang eq "applescript" && $parserState->{sodclass} eq "class") {
$sodclass = "script";
$parserState->{sodclass} = "script";
}
if ($lang eq "applescript") {
if (length($sodtype)) {
$sodname = "$sodtype $sodname";
$sodname =~ s/^\s*//sg;
$sodtype = "";
$parserState->{frozensodname} = $sodname;
}
}
if ($pascal && $parserState->{nameList}) {
$sodtype = $sodtype . $sodname;
$sodname = "";
}
if ($subparse) {
$inputCounter = $parserState->{inputCounter};
}
my $extendsClass = cppsupers($parserState->{extendsClass}, $lang, $sublang);
my $implementsClass = cppsupers($parserState->{implementsClass}, $lang, $sublang);
print STDERR "PS: $parserState\n" if ($localDebug);
my @parsedParamList = @{$parserState->{parsedParamList}};
my @pplStack = @{$parserState->{pplStack}};
my @freezeStack = @{$parserState->{freezeStack}};
if ($parserState->{prekeywordsodname}) {
print STDERR "RESTORING PRE-KEYWORD SODNAME: $sodname -> $parserState->{prekeywordsodname}\n" if ($localDebug);
$sodname = $parserState->{prekeywordsodname};
$sodtype = $parserState->{prekeywordsodtype};
}
if ($parserState->{stackFrozen}) {
print STDERR "RESTORING SODNAME: $sodname -> $parserState->{frozensodname}\n" if ($localDebug);
$sodname = $parserState->{frozensodname};
}
my $conformsToList = $parserState->{conformsToList};
my @nameObjects = ();
my $typelist = "";
my $namelist = "";
my $rawnamelist = $parserState->{lastsymbol};
if ($pascal) {
$rawnamelist = $parserState->{nameList};
}
my @variableAltNameObjects = ();
my @names = split(/[,\s;]/, $rawnamelist);
if ($parserState->{variablenames}) {
my %temp = %{$parserState->{variablenames}};
@names = keys %temp;
my $stars = "";
my $temprt = $parserState->{returntype};
if ($temprt =~ s/(\**)\s*$//s) {
$stars = $1;
}
if ($parserState->{variablestars}) {
my %stars = %{$parserState->{variablestars}};
$stars{$sodname} = $stars;
$parserState->{variablestars} = \%stars;
}
}
foreach my $insname (@names) {
my $origname = $insname;
if ($insname =~ /\S/) {
$insname =~ s/\s//so;
$insname =~ s/^[*^]//sgo;
my $newtype = $parserState->{typestring};
if ($pascal && ($parserState->{waitingForTypeInformation})) {
$newtype = $sodclass;
}
if (length($insname)) {
$typelist .= " $newtype";
$namelist .= ",$insname";
}
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $insname;
$nameobj->{TYPE} = $newtype;
if ($parserState->{variablestars}) {
my %stars = %{$parserState->{variablestars}};
$nameobj->{STARS} = $stars{$origname};
}
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "names";
push(@nameObjects, $nameobj);
if ($parserState->{variablenames}) {
push(@variableAltNameObjects, $nameobj);
}
}
}
$typelist =~ s/^ //o;
$namelist =~ s/^,//o;
if ($pascal) {
if (!length($typelist)) {
$typelist .= "$parserState->{typestring}";
$namelist .= "$psName";
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $psName;
$nameobj->{TYPE} = $parserState->{typestring};
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "Pascal type";
push(@nameObjects, $nameobj);
}
}
print STDERR "TL (PRE): $typelist\n" if ($localDebug);
if (!length($basetype)) { $basetype = $parserState->{typestring}; }
print STDERR "BT: $basetype\n" if ($localDebug);
print STDERR "NAME is $psName\n" if ($localDebug || $listDebug);
if (($psName && length($psName) && !$parserState->{simpleTypedef} && (!($HeaderDoc::outerNamesOnly || $argparse == 2) || !scalar(@nameObjects))) || !scalar(@nameObjects)) {
print STDERR "NAME BLOCK BEGIN\nNM: \"$psName\"\nSTD: $parserState->{simpleTypedef}\nONO: ".$HeaderDoc::outerNamesOnly."\nAP: $argparse\nLNL: \"".$namelist."\" (".length($namelist).")\nNAME BLOCK END\n" if ($localDebug);
if ((!length($psName)) || $namelist !~ /\Q$psName\E/) {
print STDERR "NAME AND TYPE APPENDED\n" if ($localDebug);
if (length($namelist)) {
$namelist .= ",";
$typelist .= " ";
}
$namelist .= "$psName";
$typelist .= "$basetype";
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $psName;
$nameobj->{TYPE} = $basetype;
if (!scalar(@nameObjects)) {
$nameobj->{POSSTYPES} = $posstypes;
} else {
$nameobj->{POSSTYPES} = $basetype;
}
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "Variable, enum, etc.";
push(@nameObjects, $nameobj);
}
} else {
print STDERR "Poss Anon Case\n" if ($localDebug);
if (!scalar(@names)) {
print STDERR "Empty output ($basetype, $parserState->{typestring}).\n" if ($localDebug || $listDebug);
$namelist = " ";
$typelist = "$basetype";
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = "";
$nameobj->{TYPE} = $basetype;
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "Anonymous enum";
push(@nameObjects, $nameobj);
}
print STDERR "NUMNAMES: ".scalar(@names)."\n" if ($localDebug || $listDebug);
}
print STDERR "NL: \"$namelist\".\n" if ($localDebug || $listDebug);
print STDERR "TL: \"$typelist\".\n" if ($localDebug || $listDebug);
print STDERR "PT: \"$posstypes\"\n" if ($localDebug || $listDebug);
print STDERR "SN: \"$sodname\"\nST: \"$sodtype\"\nSC: \"$sodclass\"\n" if ($localDebug || $sodDebug);
my $destructor = 0;
if ($sodtype =~ s/\~$//s) {
$sodname = "~" . $sodname;
$destructor = 1;
}
$callbackName =~ s/^.*:://o;
$callbackName =~ s/^[*^]+//o;
print STDERR "CBN: \"$callbackName\"\n" if ($localDebug || $listDebug);
print STDERR "CBNP: \"$parserState->{callbackNamePending}\"\n" if ($localDebug || $listDebug);
print STDERR "CBSN: \"$parserState->{cbsodname}\"\n" if ($localDebug || $listDebug);
if (length($callbackName)) {
if (length($parserState->{cbsodname})) {
$callbackName = $parserState->{cbsodname};
}
$psName = $callbackName;
print STDERR "DEC: \"$declaration\"\n" if ($localDebug || $listDebug);
my $cbtype = "";
$namelist = $psName;
if ($parserState->{callbackIsTypedef}) {
$cbtype = "typedef";
$typelist = "typedef";
$posstypes = "function";
} else {
$cbtype = "callback";
$typelist = "callback";
$posstypes = "function typedef";
}
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $psName;
$nameobj->{TYPE} = $cbtype;
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "callback";
if ($parserState->{callbackIsTypedef}) {
$nameobj->{ISCALLBACK} = 1;
}
push(@nameObjects, $nameobj);
print STDERR "NL: \"$namelist\".\n" if ($localDebug || $listDebug);
print STDERR "TL: \"$typelist\".\n" if ($localDebug || $listDebug);
print STDERR "PT: \"$posstypes\"\n" if ($localDebug || $listDebug);
}
if (length($parserState->{preTemplateSymbol}) && ($sodclass eq "function")) {
print STDERR "Template function detected. Changing sodname from ".$sodname." to ".$parserState->{preTemplateSymbol}."\n" if ($localDebug || $sodDebug);
$sodname = $parserState->{preTemplateSymbol};
$sodclass = "ftmplt";
print STDERR "sodclass -> ftmplt (return state)[13]\n" if ($sodDebug);
$posstypes = "ftmplt function method"; changeAll(\@nameObjects, "POSSTYPES", "ftmplt function method", 0); }
print STDERR "TVALUE: $value\n" if ($localDebug);
print STDERR "SC: \"".$sodclass."\"\n" if ($localDebug);
my $holdtypelist = 0;
if ($sodclass ne "variable") {
$value = "";
} elsif (length($value) || ($sodclass eq "variable")) {
my $varDebug = 0;
my $reset_name = 0;
if (length($value)) {
$reset_name = 1;
}
if ($parserState->{sodtypeclasstoken} && !$parserState->{ISFORWARDDECLARATION}) {
$sodtype =~ s/^\s*//s;
$sodtype = $parserState->{sodtypeclasstoken}." ".$sodtype;
}
$value =~ s/^\s*//so;
$value =~ s/\s*$//so;
if ($parserState->{constKeywordFound}) {
print STDERR "const keyword found\n" if ($localDebug || $sodDebug || $varDebug);
$sodclass = "constant";
print STDERR "sodclass -> constant (return state)[14]\n" if ($sodDebug);
$typelist = "constant";
$posstypes = "variable";
changeAll(\@nameObjects, "TYPE", "constant", 0);
changeAll(\@nameObjects, "POSSTYPES", "variable", 0);
} else {
print STDERR "const keyword NOT found\n" if ($localDebug || $sodDebug || $varDebug);
$sodclass = "variable";
print STDERR "sodclass -> variable (return state)[15]\n" if ($sodDebug);
$typelist = "variable";
$posstypes = "constant";
changeAll(\@nameObjects, "TYPE", "variable", 0);
changeAll(\@nameObjects, "POSSTYPES", "constant", 0);
}
$holdtypelist = 1;
print STDERR "Variable detected. Changing sodname from ".$sodname." to ".$parserState->{preEqualsSymbol}."\n" if ($localDebug || $sodDebug || $varDebug);
print STDERR "Changing sodclass to ".$sodclass."\nChanging posstypes to ".$posstypes."\n" if ($localDebug || $sodDebug || $varDebug);
print STDERR "TYPELIST IS ".$typelist."\n" if ($localDebug || $sodDebug || $varDebug);
if ($reset_name) {
$sodname = $parserState->{preEqualsSymbol};
}
}
if (length($parserState->{kr_c_name})) {
print STDERR "K&R C declaration detected. Changing sodname from ".$sodname." to ".$parserState->{kr_c_name}."\n" if ($localDebug || $sodDebug);
$sodname = $parserState->{kr_c_name};
$sodclass = "function";
print STDERR "sodclass -> function (return state)[16]\n" if ($sodDebug);
}
if (length($sodname) && !$parserState->{occmethod}) {
if (!length($callbackName)) { if ((!$perl_or_shell) || (!length($psName))) {
$psName = $sodname;
$namelist = $psName;
@nameObjects = @variableAltNameObjects;
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $psName;
$nameobj->{TYPE} = $sodclass;
if ($parserState->{variablestars}) {
my %stars = %{$parserState->{variablestars}};
$nameobj->{STARS} = $stars{$psName};
}
$nameobj->{POSSTYPES} = $posstypes;
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "sodname (functions, mostly)";
push(@nameObjects, $nameobj);
} else {
changeAll(\@nameObjects, "TYPE", $sodclass, 0);
}
$typelist = "$sodclass";
if (!length($parserState->{preTemplateSymbol}) && !$holdtypelist) {
$posstypes = "$sodclass";
changeAll(\@nameObjects, "POSSTYPES", $sodclass, 0);
}
print STDERR "SETTING NAME/TYPE TO $sodname, $sodclass\n" if ($sodDebug);
if ($sodclass eq "function") {
$posstypes .= " method";
changeAll(\@nameObjects, "POSSTYPES", "method", 1);
}
}
}
print STDERR "DEC: $declaration\n" if ($sodDebug || $localDebug);
if ($parserState->{occmethod}) {
$typelist = "method";
changeAll(\@nameObjects, "TYPE", "method", 0);
$posstypes = "method function";
changeAll(\@nameObjects, "POSSTYPES", "method function", 0);
if ($parserState->{occmethod} == 2) {
$namelist = "$parserState->{occmethodname}";
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $parserState->{occmethodname};
$nameobj->{TYPE} = "method";
$nameobj->{POSSTYPES} = "method function";
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "occmethod";
push(@nameObjects, $nameobj);
}
}
if ($parserState->{inMacro} == 3) {
$typelist = "#define";
$posstypes = "function method";
$namelist = $sodname;
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $sodname;
$nameobj->{TYPE} = "#define";
$nameobj->{POSSTYPES} = "function* method*";
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "CPP define";
push(@nameObjects, $nameobj);
$value = "";
@parsedParamList = ();
my $declaration = $treeTop->textTree();
if ($definename && $declaration =~ /$definename\s+\w+\(/) {
if (!$parserState->{cppMacroHasArgs}) {
warn("Dec match but not args match. Please file a bug and\ninclude a copy of this header.\n".$declaration);
}
}
if ($parserState->{cppMacroHasArgs}) {
if ($definename && $declaration !~ /$definename\s+\w+\(/) {
warn("Args match but not dec match. Please file a bug and\ninclude a copy of this header.\n".$declaration);
}
}
if ($parserState->{cppMacroHasArgs}) {
my $pplref = defParmParse($declaration, $inputCounter, $definename, $forcedebug, $fullpath);
print STDERR "parsedParamList replaced\n" if ($parmDebug);
@parsedParamList = @{$pplref};
} else {
$posstypes = "constant";
changeAll(\@nameObjects, "POSSTYPES", "constant", 0);
}
} elsif ($parserState->{inMacro} == 4) {
$typelist = "MACRO";
$posstypes = "MACRO";
$value = "";
@parsedParamList = ();
changeAll(\@nameObjects, "TYPE", "MACRO", 0);
changeAll(\@nameObjects, "POSSTYPES", "MACRO", 0);
}
if ($parserState->{inOperator}) {
$typelist = "operator";
$posstypes = "function";
changeAll(\@nameObjects, "TYPE", "operator", 0);
changeAll(\@nameObjects, "POSSTYPES", "function", 0);
}
my $privateDeclaration = "";
if ($inPrivateParamTypes) {
$privateDeclaration = $declaration;
$declaration = $publicDeclaration;
}
print STDERR "TYPELIST WAS \"$typelist\"\n" if ($localDebug);;
print STDERR "NumPPs: ".scalar(@parsedParamList)."\n" if ($localDebug);
if (scalar(@parsedParamList)) {
foreach my $stackitem (@parsedParamList) {
$stackitem =~ s/^\s*//so;
$stackitem =~ s/\s*$//so;
if (length($stackitem)) {
push(@pplStack, $stackitem);
}
}
}
if ($parserState->{stackFrozen}) {
@pplStack = @freezeStack;
}
if ($localDebug) {
foreach my $stackitem (@pplStack) {
print STDERR "stack contained $stackitem\n";
}
}
if ($parserState->{structClassName}) {
print STDERR "CHANGING NAME FROM $namelist to $parserState->{structClassName}.\n" if ($localDebug);
$namelist = $parserState->{structClassName};
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $parserState->{structClassName};
$nameobj->{TYPE} = "struct"; $nameobj->{POSSTYPES} = "";
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "Struct Class";
push(@nameObjects, $nameobj);
}
$simpleTDcontents =~ s/^\s*//so;
$simpleTDcontents =~ s/\s*;\s*$//so;
if ($simpleTDcontents =~ s/\s*\w+$//so) {
my $continue = 1;
while ($simpleTDcontents =~ s/\s*,\s*$//so) {
$simpleTDcontents =~ s/\s*\w+$//so;
}
}
if (length($simpleTDcontents)) {
my $psc = @pplStack;
print STDERR "SIMPLETYPEDEF: $inputCounter, $declaration, $typelist, $namelist, $posstypes, $value, OMITTED $psc, $returntype, $privateDeclaration, $treeTop, $simpleTDcontents, $availability\n" if ($parseDebug || $sodDebug || $localDebug);
$typelist = "typedef";
if (length($sodname)) {
$namelist = $sodname;
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $sodname;
$nameobj->{TYPE} = "typedef";
$nameobj->{POSSTYPES} = "";
$nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "Simple typedef";
push(@nameObjects, $nameobj);
} else {
changeAll(\@nameObjects, "TYPE", "typedef", 0);
changeAll(\@nameObjects, "POSSTYPES", "", 0);
}
$posstypes = "";
}
if ($parserState->{inClass} || $parserState->{inProtocol}) {
print STDERR "INCLASS!\n" if ($localDebug);
print STDERR "SODNAME WAS $sodname\n" if ($localDebug);
print STDERR "PTS: $parserState->{preTemplateSymbol}\n" if ($localDebug);
$declaration = $treeTop->textTree();
$sodtype =~ s/^\s*//s;
my @classparts = split(/\s/, $sodtype, 2);
my $classname = "";
my $superclass = "";
if (scalar(@classparts)) {
print STDERR "CLASSPARTS FOUND.\n" if ($localDebug);
$classname = $classparts[0];
$superclass = $sodname;
} else {
print STDERR "NO CLASSPARTS FOUND.\n" if ($localDebug);
$classname = $sodname;
$superclass = "";
}
if ($parserState->{inProtocol}) {
$superclass = $parserState->{extendsProtocol};
$superclass =~ s/\s+//sg;
$superclass =~ s/,,/,/sg;
$superclass =~ s/^,//sg;
$superclass =~ s/,$//sg;
$superclass =~ s/,/\cA/sg;
print STDERR "PROTOCOLSUPER: $superclass\n" if ($localDebug);
}
$namelist = $classname;
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $classname;
$nameobj->{TYPE} =$parserState->{classtype};
$nameobj->{POSSTYPES} = "$superclass"; $nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "class[1]";
push(@nameObjects, $nameobj);
$typelist = "$parserState->{classtype}";
$posstypes = "$superclass";
print STDERR "SET posstypes to \"$superclass\"\n" if ($localDebug);
changeAll(\@nameObjects, "TYPE", $parserState->{classtype}, 0);
changeAll(\@nameObjects, "POSSTYPES", $superclass, 0);
print STDERR "SUPER WAS \"$superclass\"\n" if ($localDebug);
print STDERR "categoryClass is $parserState->{categoryClass}\n" if ($localDebug || $parseDebug);
if (length($parserState->{categoryClass})) {
$posstypes = $namelist;
$posstypes =~ s/\s*//sg;
$namelist .= $parserState->{categoryClass};
$namelist =~ s/\s*//sg;
print STDERR "NL: $namelist\n" if ($localDebug || $parseDebug);
changeAll(\@nameObjects, "POSSTYPES", $posstypes, 0);
$nameObjects[0]->{NAME} .= $parserState->{categoryClass};
$nameObjects[0]->{NAME} =~ s/\s*//sg;
$nameObjects[0]->{TYPE} = $parserState->{classtype};
$nameObjects[0]->{POSSTYPES} = $posstypes; $nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameObjects[0]->{INSERTEDAT} = "class[2cat]";
my $nameobj = $nameObjects[0];
@nameObjects = ();
push(@nameObjects, $nameobj);
}
}
if ($parserState->{forceClassName}) {
$namelist = $parserState->{forceClassName};
$posstypes = cppsupers($parserState->{forceClassSuper}, $lang, $sublang);
print STDERR "CPPSUPERS: $posstypes\n" if ($localDebug);
@nameObjects = ();
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $parserState->{forceClassName};
$nameobj->{TYPE} = $parserState->{classtype};
$nameobj->{POSSTYPES} = cppsupers($parserState->{forceClassSuper}, $lang, $sublang); $nameobj->{EXTENDSCLASS} = $extendsClass;
$nameobj->{IMPLEMENTSCLASS} = $implementsClass;
$nameobj->{INSERTEDAT} = "class[3force]";
push(@nameObjects, $nameobj);
}
if ($parserState->{occSuper}) {
$posstypes = $parserState->{occSuper};
changeAll(\@nameObjects, "POSSTYPES", $parserState->{occSuper}, 0);
}
$returntype = decomment($returntype);
if (($lang eq "pascal" && length($sodtype)) ||
($lang ne "pascal" && (length($sodname) && !$parserState->{occmethod}))) {
$sodtype =~ s/\* \*/**/g;
if (!$pascal) {
$returntype = $sodtype;
print STDERR "REPLACING RETURNTYPE[4]: NOW \"$returntype\".\n" if ($retDebug);
} elsif ($parserState->{waitingForTypeInformation}) {
$returntype =~ s/^\s*:\s*//s;
$returntype =~ s/\s*;\s*$//s;
}
}
if (length($parserState->{occmethodreturntype})) {
$returntype = decomment($parserState->{occmethodreturntype});
}
print STDERR "PTDEC: ".$treeTop->textTree()."\n" if ($localDebug || $retDebug);
if ($parserState->{INMODULE}) {
print STDERR "MODULE DETECTED\n" if ($localDebug);
$sodclass = "module";
print STDERR "sodclass -> module (return state)\n[17]" if ($sodDebug);
}
cluck("Backtrace\n") if ($localDebug);
print STDERR "RETURNING NAMELIST: \"$namelist\"\nRETURNING TYPELIST: \"$typelist\"\n" if ($localDebug || $retDebug);
if (length($lastACS)) {
$HeaderDoc::AccessControlState = $lastACS;
}
print STDERR "LEFTBP\n" if ($localDebug);
if ($parserState->{isProperty}) {
print STDERR "isProperty Set.\n" if ($localDebug || $listDebug);
$typelist = "property";
$posstypes="property variable* function* method*";
$sodclass="";
print STDERR "sodclass -> \"\" (return state)[18]\n" if ($sodDebug);
changeAll(\@nameObjects, "TYPE", "property", 0);
changeAll(\@nameObjects, "POSSTYPES", "property variable* function* method*", 0);
@parsedParamList = ();
@pplStack = ();
}
if ($pascal && ($sodclass eq "enum")) {
$posstypes = "constant variable";
changeAll(\@nameObjects, "POSSTYPES", "constant variable", 0);
}
print STDERR "UPDATED:\n" if ($localDebug || $listDebug);
print STDERR "NL: \"$namelist\".\n" if ($localDebug || $listDebug);
print STDERR "TL: \"$typelist\".\n" if ($localDebug || $listDebug);
print STDERR "PT: \"$posstypes\"\n" if ($localDebug || $listDebug);
print STDERR "SN: \"$sodname\"\nST: \"$sodtype\"\nSC: \"$sodclass\"\n" if ($localDebug || $sodDebug);
if ($typelist !~ /\
$availability = mergeComplexAvailability($availability, $parserState->{availabilityNodesArray});
}
print STDERR "SUBPARSE: $subparse NAME: $namelist TTIC: ".$treeTop->{INPUTCOUNTER}." TTBO: ".$treeTop->{BLOCKOFFSET}."\n" if ($subparseDebug);
if ($subparse && defined($treeTop->{INPUTCOUNTER})) { $inputCounter = $treeTop->{INPUTCOUNTER}; } elsif ($subparse) { warn("Line numbers may be wrong [1].\n"); }
if ($subparse && defined($treeTop->{BLOCKOFFSET})) { $fileoffset = $treeTop->{BLOCKOFFSET}; } elsif ($subparse) { warn("Line numbers may be wrong [2].\n"); }
if ($parserState->{ISFORWARDDECLARATION}) {
$typelist = "forwarddeclaration-$typelist";
}
my $tempnl = "";
my $temptl = "";
my $temppt = "";
foreach my $nameobj (@nameObjects) {
$tempnl .= ",$nameobj->{NAME}";
$temptl .= " $nameobj->{TYPE}";
$temppt = "$nameobj->{POSSTYPES}";
}
$tempnl =~ s/^,//s;
$temptl =~ s/^ //s;
my $lastparm = pop(@pplStack);
print STDERR "LP: $lastparm\n" if ($localDebug || $parmDebug);
$lastparm =~ s/\s*;\s*$//s;
if ($lastparm ne "") {
push(@pplStack, $lastparm);
}
print STDERR "POSTLP: $lastparm\n" if ($localDebug || $parmDebug);
if ($lang eq "applescript") {
print STDERR "OFIN: ".$parserState->{OfIn}." ASLABEL: ".$parserState->{ASlabel}."\n" if ($parseDebug);;
if (length($parserState->{OfIn})) {
print STDERR "PUSHED ".$parserState->{OfIn}." into parsedParamList\n" if ($parseDebug || $forcedebug);
push(@pplStack, $parserState->{OfIn});
}
if (length($parserState->{ASlabel})) {
print STDERR "PUSHED ".$parserState->{ASlabel}." into parsedParamList\n" if ($parseDebug || $forcedebug);
push(@pplStack, $parserState->{ASlabel});
}
}
if ($parmDebug) {
print STDERR "PARSED PARAMETERS:";
my $count = 1;
foreach my $ppl (@pplStack) {
print "#".$count++."\n";
print $ppl."\n";
}
print STDERR "END OF PARSED PARAMETERS\n";
}
if ($sublang eq "MIG" && $parserState->{simpleTypedef}) {
$returntype = $value;
$value = "";
}
my $propertyAttributes = "";
if ($parserState->{isProperty}) {
if ($returntype =~ s/^\s*\@property\s*\((.*?)\)\s*//s) {
$propertyAttributes = $1;
}
}
my $memberOfClass = "";
my $origsodname = $sodname;
if ($sodclass eq "function" && $parserState->{isConstructor} && $lang eq "tcl") {
$memberOfClass = $sodname;
print STDERR "MEMBER OF CLASS: $memberOfClass\n" if ($localDebug || $forcedebug);
} elsif ($sublang eq "javascript" && $sodclass eq "variable" && $sodname =~ s/^(\w+(?:\.\w+)*)\s*\.\s*prototype\s*\.\s*//s) {
my $headerobj = $HeaderDoc::headerObject;
my $possible_class = $1;
my $temp = $headerobj->findClass($possible_class);
print STDERR "Checking for class \"$possible_class\"\n" if ($localDebug || $forcedebug);
if ($temp) {
$memberOfClass = $possible_class;
print STDERR "MEMBER OF CLASS: $memberOfClass\n" if ($localDebug || $forcedebug);
changeAllMatching(\@nameObjects, "NAME", "$origsodname", "NAME", "$sodname", 0);
changeAllMatching(\@nameObjects, "TYPE", "variable", "TYPE", "function", 0);
changeAllMatching(\@nameObjects, "TYPE", "variable", "POSSTYPES", "function constant variable", 0);
} else {
$sodname = $origsodname;
}
} elsif ($sodclass eq "function" && $sodtype =~ /(\w+)\s*::\s*$/) {
$memberOfClass = $1;
print STDERR "MEMBER OF CLASS: $memberOfClass\n" if ($localDebug || $forcedebug);
}
if ($localDebug || $nameObjDumpDebug) {
print STDERR "DUMPING NAME OBJECTS ON RETURN:\n";
nameObjDump(\@nameObjects);
print STDERR "RETURN TYPE: $returntype\n";
}
if ($lang eq "perl") {
@pplStack = ();
}
changeAllMatching(\@nameObjects, "TYPE", "constant", "POSSTYPES", "constant variable", 0);
changeAllMatching(\@nameObjects, "TYPE", "variable", "POSSTYPES", "constant variable", 0);
if ($sublang eq "javascript" && $sodclass eq "function") {
$posstypes = "function method class";
changeAll(\@nameObjects, "POSSTYPES", $posstypes, 0); } elsif ($lang eq "applescript" && $sodclass eq "function") {
$posstypes = "function method ".$parserState->{classtype};
changeAll(\@nameObjects, "POSSTYPES", $posstypes, 0); }
return ($inputCounter, $declaration, $typelist, $namelist, $posstypes, $value, \@pplStack, $returntype, $privateDeclaration, $treeTop, $simpleTDcontents, $availability, $fileoffset, $conformsToList, $parserState->{functionContents}, $parserState, \@nameObjects, $extendsClass, $implementsClass, $propertyAttributes, $memberOfClass, $lang, $sublang);
}
sub nameObjDump($)
{
my $arrayRef = shift;
my @objarr = @{$arrayRef};
print STDERR "DUMPING LIST\n";
foreach my $obj (@objarr) {
print STDERR "OBJECT $obj:\n";
print STDERR "\tNAME: ".$obj->{NAME}."\n";
print STDERR "\tTYPE: ".$obj->{TYPE}."\n";
print STDERR "\tPOSSTYPES: ".$obj->{POSSTYPES}."\n";
print STDERR "\tINSERTEDAT: ".$obj->{INSERTEDAT}."\n";
}
print STDERR "END DUMP\n";
}
sub findMatch($$$)
{
my $arrayRef = shift;
my $element = shift;
my $value = shift;
my @array = @{$arrayRef};
my $localDebug = 0;
foreach my $item (@array) {
print STDERR "CHECKING ELEMENT $element (".$item->{$element}.") against /$value/\n" if ($localDebug);
if ($item->{$element} =~ /$value/) {
print STDERR "MATCH\n" if ($localDebug);
return $item;
}
print STDERR "NOT MATCH\n" if ($localDebug);
}
print STDERR "NO MATCHES FOUND\n" if ($localDebug);
return undef;
}
sub changeAll($$$$)
{
my $arrayRef = shift;
my $element = shift;
my $value = shift;
my $append = shift;
my @array = @{$arrayRef};
my $localDebug = 0;
foreach my $item (@array) {
print STDERR "CHANGED $element from $item->{$element} to " if ($localDebug);
if ($append) {
$item->{$element} = $item->{$element}." ".$value;
} else {
$item->{$element} = $value;
}
print STDERR "$item->{$element}\n" if ($localDebug);
print STDERR "APPEND: $append\n" if ($localDebug);
}
}
sub changeAllMatching($$$$$$)
{
my $arrayRef = shift;
my $matchingElement = shift;
my $matchingValue = shift;
my $element = shift;
my $value = shift;
my $append = shift;
my @array = @{$arrayRef};
my $localDebug = 0;
foreach my $item (@array) {
if ($item->{$matchingElement} eq $matchingValue) {
print STDERR "CHANGED $element from $item->{$element} to " if ($localDebug);
if ($append) {
$item->{$element} = $item->{$element}." ".$value;
} else {
$item->{$element} = $value;
}
print STDERR "$item->{$element}\n" if ($localDebug);
print STDERR "APPEND: $append\n" if ($localDebug);
}
}
}
sub mergeComplexAvailability($$)
{
my $orig_avail = shift;
my $nodearrayref = shift;
if (!$nodearrayref) { return $orig_avail; }
my @nodearray = @{$nodearrayref};
foreach my $noderef (@nodearray) {
my $node = $noderef;
my @availabilitylist = @{$node->parseComplexAvailability()};
foreach my $entry (@availabilitylist) {
if (index($orig_avail, $entry) == -1) {
$orig_avail .= " ".$entry;
}
}
}
return $orig_avail;
}
sub spacefix
{
my $curline = shift;
my $part = shift;
my $lastchar = shift;
my $soc = shift;
my $eoc = shift;
my $ilc = shift;
my $ilc_b = shift;
my $localDebug = 0;
if ($HeaderDoc::use_styles) { return $curline; }
print STDERR "SF: \"$curline\" \"$part\" \"$lastchar\"\n" if ($localDebug);
if (($part !~ /[;,]/o)
&& length($curline)) {
if ($part eq $ilc || $part eq $ilc_b) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part eq $soc) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part eq $eoc) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part =~ /\(/o) {
print STDERR "PAREN\n" if ($localDebug);
if ($curline !~ /[\)\w\*]\s*$/o) {
print STDERR "CASEA\n" if ($localDebug);
if ($lastchar ne " ") {
print STDERR "CASEB\n" if ($localDebug);
$curline .= " ";
}
} else {
print STDERR "CASEC\n" if ($localDebug);
$curline =~ s/\s*$//o;
}
} elsif ($part =~ /^\w/o) {
if ($lastchar eq "\$") {
$curline =~ s/\s*$//o;
} elsif ($part =~ /^\d/o && $curline =~ /-$/o) {
$curline =~ s/\s*$//o;
} elsif ($curline !~ /[\*\(]\s*$/o) {
if ($lastchar ne " ") {
$curline .= " ";
}
} else {
$curline =~ s/\s*$//o;
}
} elsif ($lastchar =~ /\w/o) {
$curline .= " ";
}
}
if ($curline =~ /\/\*$/o) { $curline .= " "; }
return $curline;
}
sub nspaces
{
my $n = shift;
my $string = "";
while ($n-- > 0) { $string .= " "; }
return $string;
}
sub pbs
{
my @braceStack = shift;
my $localDebug = 0;
if ($localDebug) {
print STDERR "BS: ";
foreach my $p (@braceStack) { print STDERR "$p "; }
print STDERR "ENDBS\n";
}
}
sub defParmParse
{
my $declaration = shift;
my $inputCounter = shift;
my $definename = shift;
my $braceDebug = shift;
my $fullpath = shift;
my @myargs = ();
my $localDebug = 0;
my $curname = "";
$declaration =~ s/.*?$definename\s+\w+\s*\(//so;
my @braceStack = ( "(" );
my @tokens = split(/(\W)/, $declaration);
foreach my $token (@tokens) {
print STDERR "TOKEN: $token\n" if ($localDebug);
if (!scalar(@braceStack)) { last; }
if ($token =~ /[\(\[]/o) {
print STDERR "open paren/bracket - $token\n" if ($localDebug);
push(@braceStack, $token);
print STDERR "PUSHED $token ONTO BRACESTACK [8]\n" if ($braceDebug);
} elsif ($token =~ /\)/o) {
print STDERR "close paren\n" if ($localDebug);
my $top = pop(@braceStack);
print STDERR "POPPED $top FROM BRACESTACK [7]\n" if ($braceDebug);
if ($top !~ /\(/o) {
warn("$fullpath:$inputCounter: warning: Parentheses do not match (macro).\nWe may have a problem.\n");
}
} elsif ($token =~ /\]/o) {
print STDERR "close bracket\n" if ($localDebug);
my $top = pop(@braceStack);
print STDERR "POPPED $top FROM BRACESTACK [8]\n" if ($braceDebug);
if ($top !~ /\[/o) {
warn("$fullpath:$inputCounter: warning: Braces do not match (macro).\nWe may have a problem.\n");
}
} elsif ($token =~ /,/o && (scalar(@braceStack) == 1)) {
$curname =~ s/^\s*//sgo;
$curname =~ s/\s*$//sgo;
push(@myargs, $curname);
print STDERR "pushed \"$curname\"\n" if ($localDebug);
$curname = "";
} else {
$curname .= $token;
}
}
$curname =~ s/^\s*//sgo;
$curname =~ s/\s*$//sgo;
if (length($curname)) {
print STDERR "pushed \"$curname\"\n" if ($localDebug);
push(@myargs, $curname);
}
return \@myargs;
}
sub ignore
{
my $part = shift;
my $ignorelistref = shift;
my %ignorelist = %{$ignorelistref};
my $phignorelistref = shift;
my %perheaderignorelist = %{$phignorelistref};
my $localDebug = 0;
print STDERR "CHECKING TOKEN: \"$part\"\n" if ($localDebug);
my $def = $HeaderDoc::availability_defs{$part};
if ($def && length($def)) {
print STDERR "AVAILABILITY DEF FOUND: $def\n" if ($localDebug);
if ($HeaderDoc::availability_has_args{$part}) {
return 3;
}
return $def;
}
if ($ignorelist{$part}) {
print STDERR "IGNORING $part\n" if ($localDebug);
return 1;
}
if ($perheaderignorelist{$part}) {
print STDERR "IGNORING $part\n" if ($localDebug);
return 1;
}
print STDERR "NO MATCH FOUND\n" if ($localDebug);
if ($localDebug) {
print STDERR "Ignore list:\n";
foreach my $key (keys %ignorelist) {
print STDERR " ".$key." -> ".$ignorelist{$key}."\n";
}
print STDERR "\nPer-header ignore list:\n";
foreach my $key (keys %perheaderignorelist) {
print STDERR " ".$key." -> ".$perheaderignorelist{$key}."\n";
}
print STDERR "\nAvailability macros:\n";
foreach my $key (keys %HeaderDoc::availability_defs) {
print STDERR " ".$key." -> ".$HeaderDoc::availability_defs{$key}."\n";
}
}
return 0;
}
sub blockParseOutside
{
my $apiOwner = shift;
my $inFunction = shift;
my $inUnknown = shift;
my $inTypedef = shift;
my $inStruct = shift;
my $inEnum = shift;
my $inUnion = shift;
my $inConstant = shift;
my $inVar = shift;
my $inMethod = shift;
my $inPDefine = shift;
my $inClass = shift;
my $inInterface = shift;
my $blockOffset = shift;
my $categoryObjectsref = shift;
my $classObjectsref = shift;
my $classType = shift;
my $cppAccessControlState = shift;
my $fieldsref = shift;
my $fullpath = shift;
my $functionGroup = shift;
my $headerObject = shift;
my $inputCounter = shift;
my $inputlinesref = shift;
my $lang = shift;
my $nlines = shift;
my $preAtPart = shift;
my $xml_output = shift;
my $filename = basename($fullpath);
my $localDebug = shift;
my $hangDebug = shift;
my $parmDebug = shift;
my $blockDebug = shift;
my $subparse = shift;
my $subparseTree = shift;
my $nodec = shift;
my $allow_multi = shift;
my $subparseCommentTree = shift;
my $sublang = shift; if (!$sublang) {
print STDERR "WARNING: Old API use detected. Please update your\ncode to call blockParseOutside with a sublang argument.\nThis will break in a future version of HeaderDoc.\n";
cluck("Backtrace:\n");
$sublang = $HeaderDoc::sublang;
}
my $hashtreecur = shift; my $hashtreeroot = shift;
print STDERR "ALLOW_MULTI: $allow_multi\n" if ($localDebug);
my $subparseDebug = 0;
my $nameDebug = 0;
my $nameObjDebug = 0;
my $nestClassDebug = 0;
my $missingParseTreeDebug = 0;
my $mustLockDiscussion = 0;
if ($subparse && ($localDebug || $subparseDebug)) {
print "SUBPARSE COMMENT TREE: $subparseCommentTree\n";
$subparseCommentTree->dbprint();
}
if ($inClass && $nestClassDebug) {
$localDebug = 1; $blockDebug = 1; $hangDebug = 1; }
my $numcurlybraces = 0;
if ($localDebug) { if ($subparse) { print STDERR "SUBPARSE\n"; } else { print STDERR "PARSE\n"; } }
my $lastParseTree = undef;
my $slowokay = ($subparse == 2) ? 1 : 0;
my @linkobjs = ();
my $old_enable_cpp = $HeaderDoc::enable_cpp;
if ($subparse) {
$HeaderDoc::enable_cpp = -1;
}
print STDERR "IN BLOCKPARSEOUTSIDE, INPUTCOUNTER: $inputCounter BLOCKOFFSET: $blockOffset\n" if ($localDebug || $HeaderDoc::inputCounterDebug);
my @classObjects = @{$classObjectsref};
my @categoryObjects = ();
if ($categoryObjectsref) {
@categoryObjects = @{$categoryObjectsref};
}
my @fields = @{$fieldsref};
my @inputLines = @{$inputlinesref};
my @parseTrees = ();
my $methods_with_new_parser = 1;
my $curObj = undef;
my $classKeyword = "auto";
my $functionContents = "";
my $subparseInputCounter = undef;
my $subparseBlockOffset = undef;
if ($subparse && $subparseTree) {
$subparseInputCounter = $subparseTree->{LINENUM};
$subparseBlockOffset = 0;
}
my %parseTokens = %{parseTokens($lang, $sublang)};
my $foundMatch = 0;
print STDERR "blockParseOutside: APIOWNER IS $apiOwner\n" if ($localDebug);
if ($inUnknown || $inTypedef || $inStruct || $inEnum || $inUnion || $inConstant || $inVar || $inFunction || ($inMethod && $methods_with_new_parser) || $inPDefine || $inClass) {
my $varIsConstant = 0;
my $blockmode = 0;
my $blocklevel = 0;
my $curtype = "";
my $warntype = "";
my $blockDebug = 0 || $localDebug;
my $parmDebug = 0 || $localDebug;
if ($inPDefine == 2) {
print STDERR "BLOCKMODE[1] -> 1\n" if ($localDebug || $blockDebug);
$blockmode = 1;
$mustLockDiscussion = 1;
if ($subparse) {
$subparseTree = $subparseCommentTree->next();
print "LINE NUMBER NOW: ".$subparseTree->{LINENUM}."\n" if ($subparseDebug);
print "INPUT COUNTER OF TOKEN: ".$subparseTree->{INPUTCOUNTER}."\n" if ($subparseDebug);
print "BLOCK OFFSET OF TOKEN: ".$subparseTree->{BLOCKOFFSET}."\n" if ($subparseDebug);
$subparseInputCounter = $subparseTree->{LINENUM};
$subparseTree->{INPUTCOUNTER} = $subparseInputCounter;
$subparseTree->{BLOCKOFFSET} = 0;
}
}
if ($inFunction || $inMethod) {
if ($localDebug) {
if ($inMethod) {
print STDERR "inMethod\n";
} else {
print STDERR "inFunction\n";
}
}
my $method = 0;
if ($classType eq "occ" ||
$classType eq "intf" ||
$classType eq "occCat") {
if ($apiOwner !~ /^HeaderDoc::Header/) {
$method = 1;
}
}
if ($method) {
$curObj = HeaderDoc::Method->new("LANG" => $lang, "SUBLANG" => $sublang);
$curtype = "method";
} else {
$curObj = HeaderDoc::Function->new("LANG" => $lang, "SUBLANG" => $sublang);
$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);
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
if ($method) {
$curObj->processComment(\@fields);
} else {
$curObj->processComment(\@fields);
}
} elsif ($inPDefine) {
print STDERR "inPDefine\n" if ($localDebug);
$curtype = "#define";
if ($blockmode) { $warntype = "defineblock"; }
$curObj = HeaderDoc::PDefine->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->inDefineBlock($blockmode);
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
if ($mustLockDiscussion) { $curObj->discussionLocked(1); }
} elsif ($inVar) {
print STDERR "inVar\n" if ($localDebug);
$curtype = "variable";
$varIsConstant = 0;
$curObj = HeaderDoc::Var->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
} elsif ($inConstant) {
print STDERR "inConstant\n" if ($localDebug);
$curtype = "constant";
$varIsConstant = 1;
$curObj = HeaderDoc::Constant->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
} elsif ($inUnknown || $inClass) {
if ($localDebug) {
if ($inUnknown) {
print STDERR "inUnknown\n";
} else {
print STDERR "inClass\n";
}
}
$curtype = "UNKNOWN";
if ($inUnknown) {
$curObj = HeaderDoc::HeaderElement->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$classKeyword = "auto";
} else {
$curObj = HeaderDoc::APIOwner->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$classKeyword = $fields[0];
$classKeyword =~ s/^\s*\/\*\!\s*//s;
if (!length($classKeyword)) {
$classKeyword = $fields[1];
}
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "unknown", "11", \%parseTokens);
} elsif ($inTypedef) {
print STDERR "inTypedef\n" if ($localDebug);
$curtype = $parseTokens{typedefname};
$curObj = HeaderDoc::Typedef->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
$curObj->masterEnum(0);
warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "enum", "11a", \%parseTokens);
} elsif ($inStruct || $inUnion) {
if ($localDebug) {
if ($inUnion) {
print STDERR "inUnion\n";
} else {
print STDERR "inStruct\n";
}
}
if ($inUnion) {
$curtype = "union";
} else {
$curtype = "struct";
}
$curObj = HeaderDoc::Struct->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->group($HeaderDoc::globalGroup);
if ($inUnion) {
$curObj->isUnion(1);
} else {
$curObj->isUnion(0);
}
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "$curtype", "11b", \%parseTokens);
} elsif ($inEnum) {
print STDERR "inEnum\n" if ($localDebug);
$curtype = "enum";
$curObj = HeaderDoc::Enum->new("LANG" => $lang, "SUBLANG" => $sublang);
$curObj->apiOwner($apiOwner);
$curObj->masterEnum(1);
$curObj->group($HeaderDoc::globalGroup);
if ($xml_output) {
$curObj->outputformat("hdxml");
} else {
$curObj->outputformat("html");
}
$curObj->filename($filename);
$curObj->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
} else {
$curObj->linenuminblock($inputCounter);
$curObj->blockoffset($blockOffset);
}
$curObj->processComment(\@fields);
warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "$curtype", "11c", \%parseTokens);
}
my $origcurtype = $curtype;
my $firstBlockObjType = "";
my $firstBlockCurType = "";
if (!length($warntype)) { $warntype = $curtype; }
while (($inputLines[$inputCounter] !~ /\S/o) && ($inputCounter <= $nlines)){
$inputCounter++;
print STDERR "INCREMENTED INPUTCOUNTER [3]\n" if ($HeaderDoc::inputCounterDebug);
warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "$warntype", "12", \%parseTokens);
print STDERR "Input line number[7]: $inputCounter\n" if ($localDebug);
};
print STDERR "NEXT LINE is ".$inputLines[$inputCounter].".\n" if ($localDebug);
my $outertype = ""; my $newcount = 0; my $declaration = ""; my $namelist = "";
my $extendsClass = "";
my $implementsClass = "";
my $returnedParserState = undef;
my $nameObjectsRef = undef;
my ($case_sensitive, $keywordhashref) = $curObj->keywords();
my $typelist = ""; my $innertype = ""; my $posstypes = "";
print STDERR "PTCT: $posstypes =? $curtype\n" if ($localDebug || $blockDebug);
my $blockDec = "";
$localDebug = 0 || $nestClassDebug;
my $hangDebug = 0 || $localDebug;
$subparseDebug = 0 || $localDebug || $subparseDebug;
print STDERR "ENTERING IC: $inputCounter\n" if ($localDebug);
my $lastParserState = undef;
print STDERR "LOOPTEST: (($blockmode || ($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/ && !($inTypedef && $outertype =~ /^(class|\@class|\@interface|\@implementation|\@protocol)/))) && ($inputCounter <= $nlines))\n" if ($localDebug || $hangDebug || $nameDebug || $nameObjDebug || $subparseDebug);
my $previousInputCounter = $inputCounter;
my $bail = 0;
my $checkLineNumbers = 0;
my $blockCurNameAutoGenerated = 0;
my $firstDeclaration = 1;
my $realApiOwner = $apiOwner;
my $leading_linenum = $inputCounter+$blockOffset;
while (($blockmode || ($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/ && !($inTypedef && $outertype =~ /^(class|\@class|\@interface|\@implementation|\@protocol)/))) && (($inputCounter <= $nlines) || ($subparse && !$checkLineNumbers))) {
$apiOwner = $realApiOwner;
print STDERR "TOP OF LOOP: BLOCKMODE IS $blockmode\n" if ($blockDebug || $localDebug || $subparseDebug || $hangDebug);
if ($HeaderDoc::parsing_man_pages) {
while ($inputLines[$inputCounter] =~ /^\s*(or|and)\s*$/i) {
$inputCounter++;
}
}
if ($firstDeclaration) {
$firstDeclaration = 0;
} else {
if ($HeaderDoc::enableParanoidWarnings && $posstypes !~ "MACRO" && !$blockmode) {
my ($tagname, $tag_re, $superclassFieldName) = $curObj->tagNameRegexpAndSuperclassFieldNameForType();
warn("$fullpath:$leading_linenum: ".$tagname." \"".$curObj->name()."\" declaration not\nfound immediately after HeaderDoc comment. Declarations after this will\nbe treated as part of the same declaration.\n");
}
}
if ($hangDebug) { print STDERR "In Block Loop\n"; }
if ($HeaderDoc::inputCounterDebug) {
print STDERR "In block loop with blockmode: $blockmode, blocklevel = $blocklevel\n";
}
print STDERR "DOING SOMETHING\n" if ($localDebug);
print STDERR "CURRENT LINE: ".$inputLines[$inputCounter]."\n" if ($localDebug);
my $value = "";
my $pplref = undef;
my $returntype = undef;
my $propertyAttributes = undef;
my $memberOfClass = "";
my $pridec = "";
my $parseTree = undef;
my $simpleTDcontents = "";
my $bpavail = "";
my $conformsToList; print STDERR "Entering blockParse\n" if ($hangDebug);
print STDERR "ENTERING BP WITH IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
if ($subparse) {
print STDERR "subparse\n" if ($localDebug || $blockDebug || $hangDebug);
if ($lastParseTree) {
if ($subparseDebug) {
print STDERR "GOING FOR ANOTHER PARSE TREE.\n";
$lastParseTree->printTree();
}
if ($lastParserState) {
my $lastend = $lastParserState->{lastTreeNode};
$parseTree = $lastend->nextTokenNoComments($parseTokens{soc}, $parseTokens{ilc}, $parseTokens{ilc_b});
} else {
$parseTree = $lastParseTree->nextTokenNoComments($parseTokens{soc}, $parseTokens{ilc}, $parseTokens{ilc_b});
}
if ($subparseDebug) {
print STDERR "FOUND:\n";
$parseTree->printTree();
}
if (!$parseTree) {
my $curname = $curObj->name();
if (!empty_comment(@fields)) {
warn("End of parse tree reached while searching for matching declaration[1].\n");
warn "No matching declaration found. Last name was $curname\n";
warn buildCommentFromFields(@fields, $preAtPart, "The HeaderDoc comment that caused this was:\n")."\n";
warn "$outertype ne $curtype && $innertype ne $curtype && $posstypes !~ $curtype\n";
}
$HeaderDoc::enable_cpp = $old_enable_cpp;
objlink(\@linkobjs);
my $classobjref = undef; my $catobjref = undef;
$classType = undef; $blockOffset = 0;
$numcurlybraces = 0; $foundMatch = 0;
if (!$curObj->{INSERTED}) { $curObj->free(0, 1, undef); }
print STDERR "EARLY RETURN" if ($hangDebug || $localDebug || $subparseDebug);
if ($curObj->discussionLocked()) {
$curObj->unlockDiscussion();
}
return ($inputCounter, $cppAccessControlState, $classType,
$classobjref, $catobjref, $blockOffset, $numcurlybraces,
$foundMatch, $lang, $sublang, $hashtreecur, $hashtreeroot);
}
$lastParseTree = $parseTree;
} else {
print STDERR "FIRST PARSE TREE.\n" if ($subparseDebug);
$parseTree = $subparseTree;;
if ($subparseDebug && $parseTree) {
print STDERR "PARSETREE FOLLOWS:\n";
$parseTree->printTree();
} elsif ($subparseDebug) {
print STDERR "NO PARSE TREE\n";
}
print STDERR "HERE\n" if ($localDebug);
$lastParseTree = $parseTree;
if (!$parseTree) {
my $curname = $curObj->name();
if (!empty_comment(@fields)) {
warn("End of parse tree reached while searching for matching declaration[2].\n");
warn "No matching declaration found. Last name was $curname\n";
warn buildCommentFromFields(@fields, $preAtPart, "The HeaderDoc comment that caused this was:\n")."\n";
warn "$outertype ne $curtype && $innertype ne $curtype && $posstypes !~ $curtype\n";
}
$HeaderDoc::enable_cpp = $old_enable_cpp;
objlink(\@linkobjs);
my $classobjref = undef; my $catobjref = undef;
$classType = undef; $blockOffset = 0;
$numcurlybraces = 0; $foundMatch = 0;
if (!$curObj->{INSERTED}) { $curObj->free(0, 1, undef); }
if ($curObj->discussionLocked()) {
$curObj->unlockDiscussion();
}
return ($inputCounter, $cppAccessControlState, $classType,
$classobjref, $catobjref, $blockOffset, $numcurlybraces,
$foundMatch, $lang, $sublang, $hashtreecur, $hashtreeroot);
}
}
print STDERR "THERE\n" if ($localDebug);
my @ppl = ();
@ppl = $parseTree->parsedParams($lang, $sublang);
$pplref = \@ppl;
print STDERR "PPLREF is $pplref\n" if ($localDebug);
my $treestring = $parseTree->textTree();
if ($treestring !~ /\w/) {
my $curname = $curObj->name();
if (!empty_comment(@fields)) {
warn("End of parse tree reached while searching for matching declaration[3].\n");
warn "No matching declaration found. Last name was $curname\n";
warn buildCommentFromFields(@fields, $preAtPart, "The HeaderDoc comment that caused this was:\n")."\n";
warn "$outertype ne $curtype && $innertype ne $curtype && $posstypes !~ $curtype\n";
}
$HeaderDoc::enable_cpp = $old_enable_cpp;
objlink(\@linkobjs);
my $classobjref = undef; my $catobjref = undef;
$classType = undef; $blockOffset = 0;
$numcurlybraces = 0; $foundMatch = 0;
if (!$curObj->{INSERTED}) { $curObj->free(0, 1, undef); }
if ($curObj->discussionLocked()) {
$curObj->unlockDiscussion();
}
return ($inputCounter, $cppAccessControlState, $classType,
$classobjref, $catobjref, $blockOffset, $numcurlybraces,
$foundMatch, $lang, $sublang, $hashtreecur, $hashtreeroot);
}
@inputLines = ();
foreach my $line (split(/\n/, $treestring)) {
push(@inputLines, "$line\n");
}
$nlines = scalar(@inputLines) + 1000;
$inputCounter = 0;
$HeaderDoc::AccessControlState = $parseTree->acs();
$cppAccessControlState = $parseTree->acs();
my $parserState = $parseTree->parserState();
my $findstate = $parseTree;
while (!defined($parserState) && $findstate) {
print STDERR "POS IS $findstate\n" if ($localDebug);
print STDERR "POSTOKE IS ".$findstate->token()."\n" if ($localDebug);
$parserState = $findstate->parserState;
$findstate = $findstate->next();
}
if (!$parserState || $inClass) {
print STDERR "NOPARSERSTATE\n" if ($localDebug);
if (!$slowokay && !$inClass) {
$checkLineNumbers = 1;
warn("Couldn't find parser state. Using slow method.\n");
warn buildCommentFromFields(@fields, $preAtPart, "The HeaderDoc comment that caused this was:\n")."\n";
$localDebug = 1;
$hangDebug = 1;
if (0) {
warn "APIO: PT: ".$apiOwner->parseTree()."\n";
my $tree = ${$apiOwner->parseTree()};
bless($tree, "HeaderDoc::ParseTree");
print STDERR "TREE is $tree\n";
$tree->dbprint();
}
}
($newcount, $declaration, $typelist, $namelist, $posstypes, $value, $pplref, $returntype, $pridec, $parseTree, $simpleTDcontents, $bpavail, $blockOffset, $conformsToList, $functionContents, $returnedParserState, $nameObjectsRef, $extendsClass, $implementsClass, $propertyAttributes, $memberOfClass, $lang, $sublang) = &blockParse($fullpath, $blockOffset, \@inputLines, $inputCounter, 0, \%HeaderDoc::ignorePrefixes, \%HeaderDoc::perHeaderIgnorePrefixes, \%HeaderDoc::perHeaderIgnoreFuncMacros, $keywordhashref, $case_sensitive, $lang, $sublang);
if ($curObj->isAPIOwner) {
$parseTree->apiOwner($curObj);
} else {
$parseTree->addAPIOwner($curObj);
}
print STDERR "API OWNER FOR $parseTree is ".$parseTree->apiOwner()."\n" if ($localDebug);
print STDERR "NC: $newcount\n" if ($localDebug);
$numcurlybraces += $parseTree->curlycount($parseTokens{lbrace});
if ($inClass && $nestClassDebug) {
print STDERR "NESTCLASS TEST:\n";
$parseTree->dbprint();
print STDERR "END NESTCLASS TEST:\n";
print STDERR "(\$newcount, \$declaration, \$typelist, \$namelist, \$posstypes, \$value, \$pplref, \$returntype, \$pridec, \$parseTree, \$simpleTDcontents, \$bpavail, \$blockOffset) = ";
print STDERR "($newcount, DECLARATION OMITTED, $typelist, $namelist, $posstypes, $value, $pplref, $returntype, $pridec, $parseTree, $simpleTDcontents, $bpavail, $blockOffset)\n";
}
print STDERR "newcount IS $newcount\n" if ($localDebug);
print STDERR "dec is $declaration\n" if ($localDebug);
print STDERR "TYPELIST IS \"$typelist\"\n" if ($localDebug);
print STDERR "NAMELIST IS \"$namelist\"\n" if ($localDebug);
print STDERR "POSSTYPES IS \"$posstypes\"\n" if ($localDebug);
print STDERR "PPLREF IS $pplref\n" if ($localDebug);
print STDERR "RETURNTYPE IS \"$returntype\"\n" if ($localDebug);
print STDERR "parseTree IS \"$parseTree\"\n" if ($localDebug);
$lastParserState = undef;
if ($typelist eq "MACRO" && ($returntype !~ /\ if ($blockmode != 2) {
if ($inClass) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
} else {
if ($returntype =~ / $blockmode = 3;
$blocklevel++;
$curObj->isBlock(1);
print STDERR "BLOCKMODE[2] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
} elsif ($returntype =~ / $blocklevel--;
my $prev_blockmode = $blockmode;
if (!$blocklevel) { $blockmode = 0; }
print STDERR "BLOCKMODE[3] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
if ($prev_blockmode) {
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
last;
} elsif ($returntype =~ / $curObj->addParseTree(\$parseTree);
} elsif ($returntype =~ / $curObj->addParseTree(\$parseTree);
} elsif ($returntype !~ / if (@fields != ()) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
}
}
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
}
$inputCounter = $newcount;
next;
}
} else {
$parserState->{APIODONE} = 1;
my $subParseDebugPoint = (0 || $localDebug || $subparseDebug);
my $newblockoffset;
($newcount, $declaration, $typelist, $namelist, $posstypes, $value, $pplref, $returntype, $pridec, $parseTree, $simpleTDcontents, $bpavail, $newblockoffset, $conformsToList, $functionContents, $returnedParserState, $nameObjectsRef, $extendsClass, $implementsClass, $propertyAttributes, $memberOfClass, $lang, $sublang) = &blockParseReturnState($parserState, $parseTree, 0, "", 0, "", "", ($localDebug || $blockDebug), 0, $subparse, $parseTokens{definename}, $inputCounter, $lang, $sublang);
if ($curObj->isAPIOwner) {
$parseTree->apiOwner($curObj);
} else {
$parseTree->addAPIOwner($curObj);
}
print STDERR "API OWNER FOR $parseTree is ".$parseTree->apiOwner()."\n" if ($localDebug);
$numcurlybraces += $parseTree->curlycount($parseTokens{lbrace}, $parserState->{lastTreeNode});
print STDERR "newcount IS $newcount\n" if ($subParseDebugPoint);
print STDERR "dec is $declaration\n" if ($subParseDebugPoint);
print STDERR "TYPELIST IS \"$typelist\"\n" if ($subParseDebugPoint);
print STDERR "NAMELIST IS \"$namelist\"\n" if ($subParseDebugPoint);
print STDERR "POSSTYPES IS \"$posstypes\"\n" if ($subParseDebugPoint);
print STDERR "PPLREF IS $pplref\n" if ($subParseDebugPoint);
print STDERR "RETURNTYPE IS \"$returntype\"\n" if ($subParseDebugPoint);
print STDERR "parseTree IS \"$parseTree\"\n" if ($subParseDebugPoint);
print STDERR "allow_multi IS $allow_multi\n" if ($subParseDebugPoint);
$lastParserState = $parserState;
$blockOffset = $newblockoffset;
$inputCounter = $newcount;
if ($typelist eq "MACRO" && ($returntype !~ /\ if ($inClass) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
} else {
if ($blockmode != 2) {
if ($returntype =~ / $blockmode = 3;
$blocklevel++;
$curObj->isBlock(1);
print STDERR "BLOCKMODE[4] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
} elsif ($returntype =~ / $blocklevel--;
my $prev_blockmode = $blockmode;
if (!$blocklevel) { $blockmode = 0; }
print STDERR "BLOCKMODE[5] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
print STDERR "CUROBJ: $curObj\n" if ($missingParseTreeDebug);
my $temp = $curObj->parseTreeList();
if ($prev_blockmode) {
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
print STDERR "ENDIF LAST[1]: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
} elsif ($returntype =~ / $curObj->addParseTree(\$parseTree);
} elsif ($returntype !~ / if (@fields != ()) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
}
}
}
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$subparseInputCounter = $parseTree->{LINENUM};
$subparseBlockOffset = 0;
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
next;
}
$subparseInputCounter = $parseTree->{LINENUM};
$subparseBlockOffset = 0;
$declaration = $parseTree->textTree();
$curObj->linenuminblock($subparseInputCounter);
$curObj->blockoffset($subparseBlockOffset);
print STDERR "NEW INFO: LNIB: $inputCounter BO: $blockOffset\n" if ($subParseDebugPoint);
}
} else {
print STDERR "Parsing\n" if ($localDebug);
if ($nodec) {
print STDERR "NODEC\n" if ($localDebug);
$declaration = "";
$parseTree = HeaderDoc::ParseTree->new();
my @ppl = ();
$pplref = \@ppl;
$newcount = $inputCounter;
} else {
print STDERR "PREIC: $inputCounter\n" if ($localDebug);
($newcount, $declaration, $typelist, $namelist, $posstypes, $value, $pplref, $returntype, $pridec, $parseTree, $simpleTDcontents, $bpavail, $blockOffset, $conformsToList, $functionContents, $returnedParserState, $nameObjectsRef, $extendsClass, $implementsClass, $propertyAttributes, $memberOfClass, $lang, $sublang) = &blockParse($fullpath, $blockOffset, \@inputLines, $inputCounter, 0, \%HeaderDoc::ignorePrefixes, \%HeaderDoc::perHeaderIgnorePrefixes, \%HeaderDoc::perHeaderIgnoreFuncMacros, $keywordhashref, $case_sensitive, $lang, $sublang);
if ($curObj->isAPIOwner) {
$parseTree->apiOwner($curObj);
} else {
$parseTree->addAPIOwner($curObj);
}
$curObj->addToCleanup(\$parseTree);
print STDERR "PT HERE IS $parseTree\n" if ($HeaderDoc::debugAllocations);
print STDERR "API OWNER FOR $parseTree is ".$parseTree->apiOwner()."\n" if ($localDebug);
if ($localDebug) {
print STDERR "IL0: ".$inputLines[0]."\n";
print STDERR "STARTDEC\n$declaration\nENDDEC\n";
print STDERR "STARTTREE\n";
$parseTree->printTree();
print STDERR "ENDTREE\n";
}
if ($inClass) {
if ($typelist =~ "forwarddeclaration-") {
$typelist =~ s/^forwarddeclaration-//;
}
if ($typelist eq "MACRO" && ($returntype !~ /\ if ($inClass) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
} else {
if ($returntype =~ / $blockmode = 3;
$blocklevel++;
$curObj->isBlock(1);
print STDERR "BLOCKMODE[6] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
} elsif ($returntype =~ / $blocklevel--;
my $prev_blockmode = $blockmode;
if (!$blocklevel) { $blockmode = 0; }
print STDERR "BLOCKMODE[7] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
if ($prev_blockmode) {
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
print STDERR "ENDIF LAST[2]: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
} elsif ($returntype =~ / $curObj->addParseTree(\$parseTree);
} elsif ($returntype !~ / if (@fields != ()) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between class comments and class. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
}
}
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
next;
}
} else {
print STDERR "HERE TL: $typelist RT: $returntype\n" if ($HeaderDoc::inputCounterDebug);
if ($typelist eq "MACRO" && ($returntype !~ /\ if ($inClass) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
} else {
if ($returntype =~ / $blockmode = 3;
$blocklevel++;
$curObj->isBlock(1);
print STDERR "BLOCKMODE[8] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
} elsif ($returntype =~ / $blocklevel--;
my $prev_blockmode = $blockmode;
if (!$blocklevel) { $blockmode = 0; }
print STDERR "BLOCKMODE[9] -> $blockmode\n" if ($localDebug || $blockDebug);
$curObj->addParseTree(\$parseTree);
if ($prev_blockmode) {
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
print STDERR "ENDIF LAST[3]: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
if ($blocklevel) {
next;
}
last;
} elsif ($returntype =~ / $curObj->addParseTree(\$parseTree);
} elsif ($returntype !~ / if (@fields != ()) {
warn("$fullpath:".($inputCounter + $blockOffset).": warning: Macros found between comments and declaration. Ignoring.\n") if (!$HeaderDoc::running_test);
print STDERR "DEC: $declaration\n" if (!$HeaderDoc::running_test);
}
}
my ($cpphashref, $cpparghashref) = getAndClearCPPHash();
($cpphashref, $cpparghashref, $hashtreeroot, $hashtreecur) = cppHashMerge($hashtreeroot, $hashtreecur, $cpphashref, $cpparghashref, $returntype);
$hashtreeroot = $hashtreeroot; $hashtreecur = $hashtreecur;
setCPPHashes($cpphashref, $cpparghashref);
}
$inputCounter = $newcount;
next;
}
}
}
}
if ($memberOfClass ne "") {
my $temp = $realApiOwner->findClass($memberOfClass);
if ($temp) {
print STDERR "CLASSSEARCH FOUND CLASS. Will insert into class object $temp instead.\n" if ($localDebug || $nameDebug);
$apiOwner = $temp;
} else {
print STDERR "CLASSSEARCH COULD NOT FIND CLASS $memberOfClass. Will insert into header object $apiOwner.\n" if ($localDebug || $nameDebug);
}
}
print STDERR "HAVE DECLARATION NOW\n" if ($nameObjDebug);
if ($declaration !~ /\S/) {
warn("Empty declaration. Skipping to end of loop.\n") if ($localDebug || $hangDebug || $nameObjDebug || $nameDebug);
print STDERR "EMPTY: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
$inputCounter = $newcount;
last;
}
$foundMatch = 1;
if ($hangDebug) {
print STDERR "DUMPING PARSE TREE:\n";$parseTree->dbprint();print STDERR "PARSETREEDONE\n";
}
if ($bpavail && length($bpavail)) { $curObj->availability($bpavail); }
print STDERR "Left blockParse\n" if ($hangDebug);
$curObj->privateDeclaration($pridec);
$curObj->parseTree(\$parseTree);
my @parsedParamList = @{$pplref};
print STDERR "VALUE IS $value\n" if ($localDebug);
$declaration =~ s/^\s*//so;
print STDERR "obtained declaration\n" if ($localDebug);
if ($localDebug || $nameDebug) {
print STDERR "IC: $inputCounter\n";
print STDERR "DC: \"$declaration\"\n"; print STDERR "TL: \"$typelist\"\n";
print STDERR "NL: \"$namelist\"\n";
print STDERR "PT: \"$posstypes\"\n";
}
$inputCounter = $newcount;
my @oldnames = split(/[,;]/, $namelist);
my @oldtypes = split(/ /, $typelist);
my @nameObjects = @{$nameObjectsRef};
my $i=0;
if ($nameObjDebug) {
print STDERR "\n";
while ($i < scalar(@oldnames)) {
print STDERR "EXPECTED NAME: ".$oldnames[$i]."\n";
print STDERR "EXPECTED TYPE: ".$oldtypes[$i]."\n\n";
$i++;
}
foreach my $tempobj (@nameObjects) {
print STDERR "GOT NAME: ".$tempobj->{NAME}."\n";
}
foreach my $tempobj (@nameObjects) {
print STDERR "GOT TYPE: ".$tempobj->{TYPE}."\n";
}
}
my $curname = $curObj->rawname();
my $curname_extended = $curObj->rawname_extended();
$outertype = $nameObjects[0]->{TYPE};
my $outername = $nameObjects[0]->{NAME};
if ($outertype eq "") {
$outertype = $curtype;
my $linenum = $inputCounter + $blockOffset;
if ((!$nodec) && (!$HeaderDoc::running_test)) {
warn("$fullpath:$linenum: WARNING: anonymous type.\n");
warn("IC: $inputCounter\n");
warn("DC: \"$declaration\"\n");
warn("TL: \"$typelist\"\n");
warn("NL: \"$namelist\"\n");
warn("PT: \"$posstypes\"\n");
}
}
if ($outername eq "") {
if ($HeaderDoc::enableParanoidWarnings || $curname eq "") {
my $linenum = $inputCounter + $blockOffset;
my $withno = "";
if ($curname eq "") {
$withno = " with no name provided in comment";
}
if (!$HeaderDoc::running_test) {
warn("$fullpath:$linenum: WARNING: anonymous type$withno.\n");
warn("IC: $inputCounter\n");
warn("DC: \"$declaration\"\n");
warn("TL: \"$typelist\"\n");
warn("NL: \"$namelist\"\n");
warn("PT: \"$posstypes\"\n");
}
if ($curname eq "") {
my $ppstring = $parsedParamList[0];
{
$ppstring .= ";";
my @array = ( $ppstring );
my $parseTree = undef;
my $simpleTDcontents = "";
my $bpavail = "";
my $bogusblockoffset;
my $conformsToList; my ($bogusIC, $dec, $type, $name, $pt, $value, $pplref, $returntype, $pridec, $tempParseTree, $tempSimpleTDcontents, $tempbpavail, $tempbogusblockoffset, $tempConformsToList, $tempfunctionContents, $tempParserState, $tempNameObjectsRef, $ec, $ic, $propertyAttributes, $memberOfClass, $pplang, $ppsublang) = &blockParse($fullpath, ($inputCounter + $blockOffset), \@array, 0, 1, \%HeaderDoc::ignorePrefixes, \%HeaderDoc::perHeaderIgnorePrefixes, \%HeaderDoc::perHeaderIgnoreFuncMacros, $keywordhashref, $case_sensitive, $lang, $sublang);
$tempParseTree->dispose();
$curname = $name;
}
if ($curname eq "") { $curname = $curObj->firstconstname(); }
if ($curname ne "" && (!$HeaderDoc::running_test)) {
warn("Using first constant name: $curname\n");
}
$curname_extended = $curname;
}
}
}
$nodec = 0;
$innertype = $nameObjects[scalar(@nameObjects)-1]->{TYPE};
if ($localDebug) {
foreach my $obj (@nameObjects) {
my $ot = $obj->{TYPE};
print STDERR "TYPE: \"$ot\"\n";
}
}
if ($nameDebug) {
print STDERR "GOT DECLARATION.\n";
warn("IC: $inputCounter\n");
warn("DC: \"$declaration\"\n");
warn("TL: \"$typelist\"\n");
warn("NL: \"$namelist\"\n");
warn("PT: \"$posstypes\"\n");
}
my $explicit_name_differs = 1;
my $explicit_name_canonical = 0;
$curname =~ s/^\s*//o;
$curname =~ s/\s*$//o;
$curname_extended =~ s/^\s*//o;
$curname_extended =~ s/\s*$//o;
my $dropped = 0;
print STDERR "names:\n" if ($nameDebug);
if ($curname !~ /:$/o) {
foreach my $obj (@nameObjects) {
my $name = $obj->{NAME};
my $NCname = $name;
my $NCcurname = $curname;
$NCname =~ s/:$//so;
$NCcurname =~ s/:$//so;
print STDERR "NM \"$name\" CN: \"$curname\" [1]\n" if ($nameDebug);
if ($NCname eq $NCcurname && $name ne $curname) {
$curname .= ":";
$curObj->name($curname);
$curObj->rawname($curname);
}
}
}
my $conversion_requested = 0;
my $newcurtype = "UNKNOWN";
my $isCallback = 0;
print STDERR "Initial name object count: ".scalar(@nameObjects)."\n" if ($nameDebug);
foreach my $obj (@nameObjects) {
my $pt = $obj->{POSSTYPES};
if ($obj->{ISCALLBACK}) { $isCallback = 1; }
if ($curname =~ /:$/o) {
my $name = $obj->{NAME};
my $NCname = $name;
my $NCcurname = $curname;
$NCname =~ s/:$//so;
$NCcurname =~ s/:$//so;
print STDERR "NM \"$name\" CN: \"$curname\" [2]\n" if ($nameDebug);
if ($NCname eq $NCcurname && $name ne $curname) {
$curname = $NCcurname;
$curObj->name($curname);
$curObj->rawname($curname);
$curname_extended = $curObj->rawname_extended();
}
}
print STDERR "\nLOOKING FOR $curtype*\n" if ($nameDebug);
print STDERR "POSS $pt\n" if ($nameDebug);
print STDERR "NAME OBJ TYPE IS ".$obj->{TYPE}."\n" if ($nameDebug);
print STDERR "CUROBJ IS $curObj\n" if ($nameDebug);
if ((!$conversion_requested) && ($pt =~ /\Q$curtype\E\*/) && (!$curObj->{INSERTED})) {
print STDERR "MATCH: CONVERSION REQUESTED => 1\n" if ($nameDebug);
$conversion_requested = 1;
$newcurtype = $obj->{TYPE};
} elsif ($pt =~ /\Q$curtype\E/) {
print STDERR "EXACT MATCH: CONVERSION REQUESTED => -1\n" if ($nameDebug);
$conversion_requested = -1;
$newcurtype = $obj->{TYPE};
} else {
print STDERR "NO CONVERSION MATCH.\nPT: $pt\nCT: $curtype\nOT: $obj->{TYPE}\n" if ($nameDebug);
}
}
print STDERR "CR is $conversion_requested\n" if ($nameDebug);
$curname =~ s/^\s*//o;
$curname =~ s/\s*$//o;
$curname_extended =~ s/^\s*//o;
$curname_extended =~ s/\s*$//o;
print STDERR "endnames\n" if ($nameDebug);
if ((!length($curname) && $blockmode) || ($conversion_requested == 1)) {
print STDERR "CONVERSION PATH\n" if ($nameDebug);
my $allmatch = 1;
if ($conversion_requested == 1) {
print STDERR "CONVERSION REQUESTED\n" if ($nameDebug);
print STDERR "NAMES:\n" if ($nameDebug);
} else {
print STDERR "HAS NO CURNAME IN BLOCK MODE\n" if ($nameDebug);
print STDERR "NAMES:\n" if ($nameDebug);
}
my $count = 0;
print STDERR "CURTYPE: $curtype\n" if ($nameDebug);
foreach my $obj (@nameObjects) {
my $name = $obj->{NAME};
if (!length($curname)) {
$curname = $name;
print STDERR "CHANGING CURTYPE FROM $curtype to ".$obj->{TYPE}."\n" if ($nameDebug);
print STDERR "CURTYPE CHANGE[1]\n" if ($nameDebug);
$curtype = $obj->{TYPE}; if (($curtype ne $origcurtype) && ($origcurtype ne "UNKNOWN")) {
my $possfound = 0;
my $pt = $obj->{POSSTYPES}; my @ptlist = split(/\s/, $posstypes);
foreach my $pt (@ptlist) {
my $pttrim = $pt;
$pttrim =~ s/\W//sg;
if ($pttrim eq $curtype) { $possfound = 1; }
if ($pttrim eq $curtype."*") { $possfound = 2; }
print STDERR "CMP_P $pttrim $curtype\n" if ($nameDebug);
}
if (!$possfound) {
warn "WARNING: Not all types in block match ($curtype != $origcurtype).\n";
}
}
} elsif ($name ne $curname) {
print STDERR "NAMEMATCH: $name NE $curname\n" if ($nameDebug);
$allmatch = 0;
}
print STDERR "NAME: $name\n" if ($nameDebug);
$count++;
}
$curname =~ s/^\s*//o;
$curname =~ s/\s*$//o;
if ($conversion_requested == 1) {
print STDERR "CURTYPE CHANGE[2]\n" if ($nameDebug);
$curObj->origType($curtype);
$curtype = $newcurtype;
}
print STDERR "CURTYPE NOW: $curtype\n" if ($nameDebug);
print STDERR "ENDNAMES:\n" if ($nameDebug);
if (!$allmatch && !$conversion_requested) {
warn "WARNING: No name found in block mode and names do not match. Using first.\n" if (!$HeaderDoc::running_test);
}
my $newcurObj;
my $typestring = $curtype;
my $ncdeclaration = $parseTree->textTreeNC($lang, $sublang, 1);
($newcurObj, $classType, $varIsConstant) = objForType( $curObj, $parseTokens{typedefname}, $typestring,
$posstypes, $outertype, $curtype, $classType, $classKeyword, $ncdeclaration,
\@fields, $functionGroup, $varIsConstant, $blockmode, $inClass, $inInterface,
$inTypedef, $inStruct, $fullpath, $inputCounter, $blockOffset, $lang, $sublang, 0, $functionContents,
$apiOwner, $subparseInputCounter, $subparseBlockOffset, $extendsClass, $implementsClass, 1, \%parseTokens);
if ($mustLockDiscussion) {
$curObj->prepareDiscussionForTemporary();
}
print STDERR "CUROBJ ON RETURN: $curObj\n" if ($nameDebug);
print STDERR "NEWCUROBJ ON RETURN: $newcurObj\n" if ($nameDebug);
my @keys = keys %{$curObj};
print STDERR "Cloning object $curObj to $newcurObj...\n" if ($nameDebug);
foreach my $key (@keys) {
if ($key ne "CLASS") {
$newcurObj->{$key} = $curObj->{$key};
}
}
print STDERR "NEWCUROBJ AFTER CLONE: $newcurObj\n" if ($nameDebug);
print STDERR "NEWCUROBJ CLASS AFTER CLONE: ".$newcurObj->{CLASS}."\n" if ($nameDebug);
my $group = $curObj->group();
$newcurObj->group($group);
$curObj->apiOwner()->removeFromGroup($group, $curObj);
$parseTree->apiOwnerSub($curObj, $newcurObj);
$curObj->dbprint() if ($HeaderDoc::debugAllocations);
if (!$curObj->{INSERTED}) { $curObj->free(0, 1, $newcurObj); }
print STDERR "Replacing $curObj with $newcurObj\n" if ($HeaderDoc::debugAllocations);
$curObj = $newcurObj;
$curObj->apiOwner($apiOwner);
$blockCurNameAutoGenerated = 1;
} elsif ($blockCurNameAutoGenerated == 1) {
my $count = 0;
print STDERR "CURNAME AUTO PATH (BLOCKMODE $blockmode)\n" if ($nameDebug);
my $allmatch = 1;
my $typematch = 1;
foreach my $obj (@nameObjects) {
my $name = $obj->{NAME};
if (!length($curname)) {
$curname = $name;
if (!length($curtype)) {
print STDERR "CURTYPE CHANGE[3]\n" if ($nameDebug);
$curtype = $obj->{TYPE}; } elsif ($curtype ne $obj->{TYPE}) {
$typematch = 0;
}
} elsif ($name ne $curname) {
$allmatch = 0;
}
print STDERR "NAME: $name\n" if ($nameDebug);
$count++;
}
if (!$allmatch || !$typematch) {
if (!$allmatch) {
warn "WARNING: No name found in block mode and names do not match. Using first.\n" if (!$HeaderDoc::running_test);
}
if (!$typematch) {
warn "WARNING: No name found in block mode and types do not match. Using first.\n" if (!$HeaderDoc::running_test);
}
$curname .= "_multideclaration_block";
$blockCurNameAutoGenerated = 2;
}
}
$curObj->parserState($returnedParserState);
if (!$firstBlockObjType) {
$firstBlockObjType = $newcurtype;
$firstBlockCurType = $curtype;
}
print STDERR "ORIG CURTYPE $origcurtype FIRST CURTYPE WAS $firstBlockCurType\n".
"CURTYPE $curtype INFUNCTION: $inFunction\n" if ($nameObjDebug || $nameDebug);
my $docname = "";
my $found = $blockmode;
print STDERR "Current APIOwner is ".$apiOwner->name()."\n" if ($localDebug || $nameDebug);
foreach my $obj (@nameObjects) {
my $ottrim = $obj->{TYPE};
$ottrim =~ s/\W//sg;
if ($ottrim eq "define") { $ottrim = "#define"; }
if ($ottrim eq $curtype) { $found = 1; }
print STDERR "CMP_O $ottrim $curtype\n" if ($nameDebug);
}
my @ptlist = split(/\s/, $posstypes);
foreach my $obj (@nameObjects) {
my $pt = $obj->{POSSTYPES}; my @ptlist = split(/\s/, $posstypes);
foreach my $pt (@ptlist) {
my $pttrim = $pt;
$pttrim =~ s/\W//sg;
if ($pttrim eq $curtype) { $found = 1; }
if ($pttrim eq $curtype."*") { $found = 2; }
print STDERR "CMP_P $pttrim $curtype\n" if ($nameDebug);
}
}
my $curname_inserted = 0;
my $curObjIsTainted = 0;
if (length($curname) && length($curtype)) {
print STDERR "HAS CURNAME\n" if ($nameDebug);
my $foundName = findMatch(\@nameObjects, "NAME", '\S');
if ($found || !$foundName) {
if (!$foundName) {
print STDERR "Explicit name is canonical name\n" if ($nameDebug);
$explicit_name_canonical = 1;
} else {
print STDERR "Found matching name\n" if ($nameDebug);
}
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $curname;
$nameobj->{TYPE} = $outertype;
$nameobj->{POSSTYPES} = $nameObjects[0]->{POSSTYPES};
$nameobj->{INSERTEDAT} = "OUTER 1";
$nameobj->{ACTIVE} = 1;
print STDERR "CREATING AS ACTIVE: $curname\n" if ($nameObjDebug);
if (($curtype ne $outertype) && !$explicit_name_canonical && !$blockmode) {
print STDERR "TYPE MISMATCH for $nameobj" if ($nameDebug);
$curObj->unregister();
$curObjIsTainted = $nameobj;
} else {
@nameObjects = ( ($nameobj), (@nameObjects));
$curname_inserted = 1;
}
} else {
print STDERR "NOT FOUND AND NAME COUNT NONZERO\n" if ($nameDebug);
}
} else {
print STDERR "HAS NO CURNAME NOT IN BLOCK MODE\n" if ($nameDebug);
}
my $on = scalar(@nameObjects);
print STDERR "NUMNAMES: ".scalar(@nameObjects).", FOUND: $found CURNAME: $curname, ".$curObj->name."\n" if ($nameDebug);
if ($localDebug || $nameDebug) {
foreach my $nameObj (@nameObjects) {
my $name = $nameObj->{NAME};
my $type = $nameObj->{TYPE};
print STDERR "NAME $name TYPE $type\n";
}
}
my $count = 0;
my $operator = 0;
if ($curObjIsTainted) {
my $foundMatchWithTaintedObject = 0;
foreach my $obj (@nameObjects) {
if ($obj == $curObjIsTainted) {
next;
}
if ($obj->{NAME} eq $curObjIsTainted->{NAME}) {
$foundMatchWithTaintedObject = 1;
}
}
if (!$foundMatchWithTaintedObject) {
@nameObjects = ( ($curObjIsTainted), (@nameObjects));
$curname_inserted = 1;
}
}
foreach my $obj (@nameObjects) {
if ($obj->{ACTIVE}) {
next;
}
my $operator = 0;
if ($obj->{TYPE} eq "operator") {
$operator = 1;
}
print STDERR "OPERATOR: $operator\n" if ($nameDebug || $nameObjDebug);
if (!length($obj->{NAME})) {
next;
}
if ($operator) {
$obj->{NAME} =~ s/^\s*operator\s*//so;
$obj->{NAME} = "operator ".$obj->{NAME};
$curname =~ s/^operator(\s*)(\S+)/operator $2/so;
}
print STDERR "NAME \"$obj->{NAME}\"\nCURNAME \"$curname\"\nOUTERTYPE \"$outertype\"\nOBJTYPE \"".$obj->{TYPE}."\"\n" if ($nameDebug);
if ((($obj->{NAME} eq $curname) && ($obj->{TYPE} eq $outertype)) && $curname_inserted) {
print STDERR "Explicit name matches parsed.\n" if ($nameDebug);
$explicit_name_differs = 0;
$count++;
} else {
print STDERR "Explicit name ($curname) does NOT match parsed ($obj->{NAME}) or type ($outertype) does not match (".$obj->{TYPE}.") or not curname_inserted ($curname_inserted). Adding to list.\n" if ($nameDebug);
if (($obj->{NAME} eq $curname)) { $curname_inserted = 1; }
print STDERR "DOCNAME: $curname\n" if ($nameDebug);
$docname = $curname;
print STDERR "ACTIVATING: $obj->{NAME}\n" if ($nameObjDebug);
$obj->{ACTIVE} = 1;
}
}
if ($hangDebug) { print STDERR "Point A\n"; }
print STDERR "END: $explicit_name_differs; ENC: $explicit_name_canonical\n" if ($nameDebug);
if ($explicit_name_differs && !$explicit_name_canonical && ($curname_inserted || $curname =~ /\W/) && $found) {
print STDERR "Setting APPLEREFISDOC for $curObj : \"".$curObj->name()."\" [1]\n" if ($nameDebug);
$curObj->appleRefIsDoc(1);
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $curObj->apirefSetup(1);
print STDERR "APIREF: ".$curObj->apiref()."\n" if ($nameDebug);
$HeaderDoc::ignore_apiuid_errors = $prevignore;
} else {
if ($curname_extended =~ /[^\w\:]/) {
print STDERR "Setting APPLEREFISDOC for $curObj : \"".$curObj->name()."\" [2]\n" if ($nameDebug);
if ($explicit_name_canonical) {
$curObj->appleRefIsDoc(2);
} else {
$curObj->appleRefIsDoc(1);
}
if ($curObj->{INSERTED}) {
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $curObj->apirefSetup(1);
print STDERR "APIREF: ".$curObj->apiref()."\n" if ($nameDebug);
$HeaderDoc::ignore_apiuid_errors = $prevignore;
}
} else {
print STDERR "Clearing APPLEREFISDOC for $curObj : ".$curObj->name()."\n" if ($nameDebug);
$curObj->appleRefIsDoc(0);
if ($curObj->{INSERTED}) {
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $curObj->apirefSetup(1);
print STDERR "APIREF: ".$curObj->apiref()."\n" if ($nameDebug);
$HeaderDoc::ignore_apiuid_errors = $prevignore;
}
}
}
print STDERR "CUROBJ IS $curObj\n" if ($nameDebug);
my $matching_declaration = 0;
if ($outertype eq $curtype || $innertype eq $curtype || findMatch(\@nameObjects, "POSSTYPES", $curtype)) {
if (findMatch(\@nameObjects, "POSSTYPES", $curtype.'\*')) {
$matching_declaration = 2;
} else {
$matching_declaration = 1;
}
$curObj->declaration($declaration);
} elsif ($curtype eq "UNKNOWN") {
$matching_declaration = 1;
} else {
print STDERR "NOMATCH: OUTER: $outertype CUR: $curtype INNER: $innertype\n" if ($nameDebug);
}
$count = 0;
print STDERR "ENTERING NAMEOBJECT LOOP. CURTYPE IS $curtype CUROBJ is $curObj\n" if ($nameObjDebug || $nameDebug);
foreach my $obj (@nameObjects) {
print STDERR "IN NAMEOBJECT LOOP. CURTYPE IS $curtype CUROBJ is $curObj\n" if ($nameObjDebug || $nameDebug);
if (!$obj->{ACTIVE}) {
print STDERR "SKIPPING OBJECT $obj (NAME ".$obj->{NAME}.") because it is inactive\n" if ($nameDebug || $nameObjDebug);
next;
} else {
print STDERR "ADDING OBJECT $obj (NAME ".$obj->{NAME}.") because it is active\n" if ($nameDebug || $nameObjDebug);
}
my $name = $obj->{NAME};
my $typestring = $obj->{TYPE};
my $posstypes = $obj->{POSSTYPES};
my $outerLocalDebug = $localDebug;
my $localDebug = 0 || $nameDebug || $nestClassDebug;
my $rawname = $name;
print STDERR "NAME IS \"$name\"\n" if ($localDebug);
print STDERR "CURNAME IS \"$curname\"\n" if ($localDebug);
print STDERR "TYPESTRING IS $typestring\n" if ($localDebug);
print STDERR "CURTYPE IS $curtype\n" if ($localDebug);
print STDERR "MATCH: $name IS A $typestring.\n" if ($localDebug);
print STDERR "DEC ($name / $typestring): $declaration\n" if ($localDebug && $outerLocalDebug);
$name =~ s/\s*$//go;
$name =~ s/^\s*//go;
my $cmpname = $name;
my $cmpcurname = $curname;
$cmpname =~ s/:$//so;
$cmpcurname =~ s/:$//so;
if (!length($name)) { next; }
my $extra_needs_setup = 0;
print STDERR "Got $name ($curname)\n" if ($localDebug);
print STDERR "POSSTYPES: $posstypes\n" if ($nameDebug || $nameObjDebug);
print "CUROBJ CHECKPOINT: $curObj\n" if ($nameObjDebug);
my $extra = undef;
if ($blockmode && ($typestring ne $firstBlockObjType) && ($typestring ne $firstBlockCurType)) {
warn "WARNING: Block declaration contains multiple types\n ($typestring != $firstBlockObjType)\n";
}
print "CUROBJ: $curObj INSERTED: $curObj->{INSERTED}\n" if ($nameDebug);
if ((!$curObjIsTainted) && (($typestring eq $curtype && ($cmpname eq $cmpcurname || !length($curname))) && ((!$curObj->{INSERTED}) || $typestring eq $firstBlockCurType))) {
print STDERR "$curtype = $typestring\n" if ($localDebug);
$extra = $curObj;
print STDERR "EXTRA IS CUROBJ ($extra) FROM NAME OBJECT $obj\n" if ($nameObjDebug);
if ($curObj->{INSERTED}) {
$curObj->{INSERTED} = 2;
} else {
$curObj->{INSERTED} = 1;
}
push(@linkobjs, \$extra);
if ($blockmode) {
$blockDec .= $declaration;
print STDERR "SPDF[1]\n" if ($hangDebug);
$curObj->isBlock(1);
print STDERR "END SPDF[1]\n" if ($hangDebug);
}
} else {
$extra_needs_setup = 1;
print STDERR "NAME IS $name\n" if ($localDebug);
if ($curtype eq "function" && $posstypes =~ /function/o) {
$curtype = "UNKNOWN";
print STDERR "setting curtype to UNKNOWN\n" if ($localDebug);
}
if ($typestring =~ /forwarddeclaration-/) {
$bail = 1;
print STDERR "BAILFAST[1]: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
}
my $ncdeclaration = $parseTree->textTreeNC($lang, $sublang, 1);
($extra, $classType, $varIsConstant) = objForType( $curObj, $parseTokens{typedefname}, $typestring,
$posstypes, $outertype, $curtype, $classType, $classKeyword, $ncdeclaration,
\@fields, $functionGroup, $varIsConstant, $blockmode, $inClass, $inInterface,
$inTypedef, $inStruct, $fullpath, $inputCounter, $blockOffset, $lang, $sublang, $outerLocalDebug,
$functionContents, $apiOwner, $subparseInputCounter, $subparseBlockOffset,
$extendsClass, $implementsClass, 0, \%parseTokens);
print "EXTRA ON RETURN IS $extra\n" if ($nameDebug || $nameObjDebug);
}
my $class = ref($extra) || $extra;
if ($class =~ /HeaderDoc::HeaderElement/) {
next;
}
if ($extra) {
$extra->parserState($returnedParserState);
if ($matching_declaration) {
$extra->suppressChildren(0);
} else {
$extra->suppressChildren(1);
}
}
if ($hangDebug) { print STDERR "Point NEWB\n"; }
if ($curtype eq "UNKNOWN" && $extra && !$blockmode) {
my $orig_parsetree_ref = $curObj->parseTree();
bless($orig_parsetree_ref, "HeaderDoc::ParseTree");
my $pt = ${$orig_parsetree_ref};
if ((!$curObj->{INSERTED}) && ($curObj != $extra)) { $curObj->free(0, 1, $extra); }
$curObj = $extra;
$curObj->apiOwner($apiOwner);
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 2;
$HeaderDoc::ignore_apiuid_errors = $prevignore;
if ($extra->isAPIOwner) {
$pt->apiOwner($extra);
} else {
$pt->addAPIOwner($extra);
}
$curObj->parseTree($orig_parsetree_ref);
} else {
print STDERR "NOT SETTING PARSETREE. Current type is $curtype\n"."\n" if ($missingParseTreeDebug);
print STDERR "CUROBJ IS $curObj\n" if ($missingParseTreeDebug);
print STDERR "CUROBJ PT IS".$curObj->parseTree()."\n" if ($missingParseTreeDebug);
}
if ($extra) {
print STDERR "Processing \"extra\" ($extra).\n" if ($localDebug);
print STDERR "EXTRANAME: \"".$name."\"\n" if ($localDebug);
if ($isCallback) {
if ($extra->can("isFunctionPointer")) {
$extra->isFunctionPointer($isCallback);
}
}
if ($bpavail && length($bpavail)) {
$extra->availability($bpavail);
}
my $cleantypename = "$typestring $name";
$cleantypename =~ s/\s+/ /sgo;
$cleantypename =~ s/^\s*//so;
$cleantypename =~ s/\s*$//so;
if (length($cleantypename)) {
$HeaderDoc::namerefs{$cleantypename} = $extra;
$extra->addToNameRefs($cleantypename);
}
my $extraclass = ref($extra) || $extra;
my $abstract = $curObj->abstract();
my $discussion_set = $curObj->discussion_set();
my $discussion = $curObj->raw_discussion();
my $override_discussion = undef;
my $nameline_discussion = $curObj->raw_nameline_discussion();
print STDERR "OLD DISCUSSION: $discussion\n" if ($nameDebug);
print STDERR "OLD NAMELINE DISCUSSION: $nameline_discussion\n" if ($nameDebug);
my $pridec = $curObj->privateDeclaration();
$extra->privateDeclaration($pridec);
if ($curObj != $extra) {
my $orig_parsetree_ref = $curObj->parseTree();
print STDERR "CO != EX. PTREF is $orig_parsetree_ref\n"."\n" if ($missingParseTreeDebug);
bless($orig_parsetree_ref, "HeaderDoc::ParseTree");
if ($extra->isAPIOwner) {
$$orig_parsetree_ref->apiOwner($extra);
} else {
$$orig_parsetree_ref->addAPIOwner($extra);
}
$extra->parseTree($orig_parsetree_ref); } else {
print STDERR "CO == EX.\n"."\n" if ($missingParseTreeDebug);
}
if ($blockmode) {
my $parmDescDebug = $parmDebug || 0;
print STDERR "Looking for discussion for \"$name\"\n" if ($parmDescDebug);
my $discussionParam = $curObj->taggedParamMatching($name);
print STDERR "GOT OBJECT $discussionParam\n" if ($parmDescDebug);
print STDERR "SELF: $curObj DP: $discussionParam\n" if ($parmDescDebug); if ($discussionParam) {
my $altdiscussion = $discussionParam->halfbaked_discussion();
print "AD IS: $altdiscussion\n" if ($parmDescDebug);
if ($altdiscussion =~ /\S/) { $override_discussion = $altdiscussion; }
$discussionParam->{MAINOBJECT} = \$extra;
}
if ($curObj != $extra) {
$curObj->addParsedParameter($extra);
}
}
print STDERR "Point B1\n" if ($hangDebug);
if ($extraclass ne "HeaderDoc::Method" && !$extra->isAPIOwner()) {
print STDERR "Point B2\n" if ($hangDebug);
my $paramName = "";
my $position = 0;
my $type = "";
if ($extraclass eq "HeaderDoc::Function") {
$extra->returntype($returntype);
}
my @tempPPL = @parsedParamList;
foreach my $parsedParam (@tempPPL) {
my $ppDebug = 0 || $parmDebug;
print STDERR "PARSED PARAM: \"$parsedParam\"\n" if ($ppDebug);
my $ppstring = $parsedParam;
$ppstring =~ s/^\s*//sgo;
$ppstring =~ s/\s*$//sgo;
my $foo;
my $dec;
my $pridec;
my $type;
my $name;
my $pt;
my $value;
my $pplref;
my $returntype;
my @nameObjects = ();
my $pplang = $lang;
my $ppsublang = $sublang;
if ($ppstring eq "...") {
my $nameobj = HeaderDoc::TypeHelper->new();
$nameobj->{NAME} = $ppstring;
$nameobj->{TYPE} = "";
$nameobj->{POSSTYPES} = "";
$nameobj->{INSERTEDAT} = "varargs";
push(@nameObjects, $nameobj);
} else {
$ppstring .= ";";
my @array = ( $ppstring );
my $parseTree = undef;
my $simpleTDcontents = "";
my $bpavail = "";
my $bogusblockoffset;
my $conformsToList; my $ec = ""; my $ic = "";
my $argreturnedParserState;
($foo, $dec, $type, $name, $pt, $value, $pplref, $returntype, $pridec, $parseTree, $simpleTDcontents, $bpavail, $bogusblockoffset, $conformsToList, $functionContents, $argreturnedParserState, $nameObjectsRef, $ec, $ic, $propertyAttributes, $memberOfClass, $pplang, $ppsublang) = &blockParse($fullpath, $extra->linenum(), \@array, 0, 1, \%HeaderDoc::ignorePrefixes, \%HeaderDoc::perHeaderIgnorePrefixes, \%HeaderDoc::perHeaderIgnoreFuncMacros, $keywordhashref, $case_sensitive, $lang, $sublang);
$parseTree->dispose();
@nameObjects = @{$nameObjectsRef};
}
if ($ppDebug) {
print STDERR "NAME: $name\n";
print STDERR "TYPE: $type\n";
print STDERR "PT: $pt\n";
print STDERR "RT: $returntype\n";
}
foreach my $obj (@nameObjects) {
my $name = $obj->{NAME};
my $stars = $obj->{STARS};
print STDERR "NAME: $name TYPE: $returntype\n" if ($ppDebug);
my $param = HeaderDoc::MinorAPIElement->new("LANG" => $pplang, "SUBLANG" => $ppsublang);
$param->apiOwner($apiOwner);
if (defined($subparseInputCounter)) {
$param->linenuminblock($subparseInputCounter);
$param->blockoffset($subparseBlockOffset);
} else {
$param->linenuminblock($inputCounter);
$param->blockoffset($blockOffset);
}
$param->outputformat($extra->outputformat);
$returntype =~ s/^\s*//s;
$returntype =~ s/\s*$//s;
if ($obj->{NAME} eq "") {
warn("Anonymous data structure inside struct or union.\n");
warn("LISTING:\n$parsedParam\nEND LISTING\n");
warn("OWNER IS: $rawname\n");
next;
}
print STDERR "BLOCKPARSE PARAMETER PARSE RETURNED NAME $obj->{NAME}\n" if ($ppDebug);
print STDERR "RETURNTYPE IS $returntype\n" if ($ppDebug);
if ($extraclass =~ /HeaderDoc::Function/ && $ppsublang ne "php") {
my $enumname = $parseTokens{enumname};
my $typedefname = $parseTokens{typedefname};
my $structname = $parseTokens{structname};
my $unionname = $parseTokens{unionname};
if ($pplang ne "pascal" && $ppsublang ne "MIG" &&
(($structname && $returntype =~ /(^|\s)\Q$structname\E$/) ||
($unionname && $returntype =~ /(^|\s)\Q$unionname\E$/) ||
($enumname && $returntype =~ /(^|\s)\Q$enumname\E$/) ||
($typedefname && $returntype =~ /(^|\s)\Q$typedefname\E$/))) {
print STDERR "OOPS\n";
$returntype .= " ".$obj->{NAME};
$name = "";
} elsif (!length($returntype)) {
$returntype .= " $name";
if ($name !~ /\.\.\./) {
$name = ""; }
}
}
print STDERR "NM: $name RT $returntype\n" if ($ppDebug);
$param->name($name);
$param->position($position++);
my $typeval = $returntype;
if ($stars) { $typeval .= " ".$stars; }
$param->type($typeval);
$extra->addParsedParameter($param);
}
}
} elsif ($extraclass eq "HeaderDoc::Method") {
$extra->returntype($returntype);
my @newpps = $parseTree->objCparsedParams($lang, $sublang);
foreach my $newpp (@newpps) {
$extra->addParsedParameter($newpp);
}
}
if ($extra->{CLASS} ne "HeaderDoc::PDefine" && $blockmode == 2) {
my $linenum = $inputCounter + $blockOffset;
warn("$fullpath:$linenum: warning: Unterminated \@defineblock detected.\n");
$blockmode = 0;
print STDERR "\$extra->{CLASS}=\"".$extra->{CLASS}."\"\n" if ($localDebug);
if (!$subparse) {
my $poplines = 0;
print STDERR "Previous line number was ".($previousInputCounter + $blockOffset).".\n" if ($localDebug);
$inputCounter = $previousInputCounter;
while ($inputCounter >= 1) {
my $checkline = $inputLines[$inputCounter];
print STDERR "IC: $inputCounter CL: $checkline\n" if ($localDebug);
if ($checkline =~ /\/\*\!/) { last; }
if ($checkline =~ /\ while ($checkline =~ /\\\s*$/) {
$inputCounter++;
print STDERR "INCREMENTED INPUTCOUNTER [5]\n" if ($HeaderDoc::inputCounterDebug);
$checkline = $inputLines[$inputCounter];
}
$inputCounter++;
print STDERR "INCREMENTED INPUTCOUNTER [6]\n" if ($HeaderDoc::inputCounterDebug);
last;
}
$inputCounter--;
print STDERR "DECREMENTED INPUTCOUNTER [7]\n" if ($HeaderDoc::inputCounterDebug);
$poplines++;
}
$inputCounter--;
print STDERR "DECREMENTED INPUTCOUNTER [8]\n" if ($HeaderDoc::inputCounterDebug);
$curObj->dropParsedParameter();
$bail = 1;
print STDERR "BAILFAST[2]: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
}
}
if (length($simpleTDcontents)) {
$extra->typedefContents($simpleTDcontents);
}
print STDERR "Point B3\n" if ($hangDebug || $nameDebug);
print STDERR "AT BOTTOM: DISCUSSION IS: ".($override_discussion ? $override_discussion : $discussion)."\n" if ($parmDebug);
if ($preAtPart =~ /\S/) {
print STDERR "preAtPart: $preAtPart\n" if ($localDebug);
if (($blockmode == 2) && $extra->can("blockDiscussion")) {
$extra->blockDiscussion($preAtPart);
if ($override_discussion) {
$extra->discussion($override_discussion);
}
} else {
$extra->discussion(($override_discussion ? $override_discussion : $preAtPart));
}
} elsif ($extra != $curObj) {
print STDERR "SETTING DISCUSSION: extra != CurObj\n" if ($parmDebug);
if ($blockmode == 1 || $blockmode == 2) {
if (!$discussion) {
print STDERR "SETTING DISCUSSION: blockmode == 2 and NO discussion\n" if ($parmDebug);
$extra->blockDiscussion($nameline_discussion);
} else {
print STDERR "SETTING DISCUSSION: blockmode == 2 and discussion\n" if ($parmDebug);
$extra->blockDiscussion($discussion);
}
if ($override_discussion) {
$extra->discussion($override_discussion);
}
} else {
if ($discussion_set || $override_discussion) {
print STDERR "SETTING DISCUSSION: blockmode NOT 2 and discussion_set\n" if ($parmDebug);
$extra->discussion(($override_discussion ? $override_discussion : $discussion));
print STDERR "NEW DISC IS $discussion\n" if ($parmDebug);
} else {
print STDERR "SETTING DISCUSSION: blockmode NOT 2 and NOT discussion_set\n" if ($parmDebug);
$extra->nameline_discussion($nameline_discussion);
}
}
}
print STDERR "Point B4\n" if ($hangDebug || $nameDebug);
$extra->abstract($abstract);
if (length($value)) { $extra->value($value); }
if ($extra != $curObj || !length($curObj->name())) {
$name =~ s/^(\s|\*)*//sgo;
}
print STDERR "NAME IS \"$name\"\n" if ($localDebug || $nameDebug);
$extra->rawname($name);
print STDERR "RN: \"".$extra->rawname()."\"\n" if ($localDebug || $nameDebug);
print STDERR "NM: \"".$extra->name()."\"\n" if ($localDebug || $nameDebug);
print STDERR "Point B5\n" if ($hangDebug);
$extra->name($name);
if ($extra =~ /HeaderDoc::ObjC/) {
$extra->conformsToList($conformsToList)
}
if ($extra != $curObj) {
my @params = $curObj->taggedParameters();
foreach my $param (@params) {
print STDERR "CONSTANT $param\n" if ($parmDebug);
if (!$param->{ISDEFINE}) {
my $newparam = $param->clone();
$newparam->apiOwner($extra);
$extra->addTaggedParameter($newparam);
} elsif ($param->name() eq $extra->rawname() || $param->name() eq $extra->name()) {
my @subparams = $param->userDictArray();
print "SP: ".@subparams."\n" if ($parmDebug);
foreach my $hashRef (@subparams) {
while (my ($param, $disc) = each %{$hashRef}) {
print STDERR "PARAM IS $param\n" if ($parmDebug);
my $paramobj = HeaderDoc::MinorAPIElement->new("LANG" => $lang, "SUBLANG" => $sublang);
$paramobj->name($param);
$paramobj->discussion($disc);
$extra->addTaggedParameter($paramobj);
}
}
} else {
print STDERR "NOMATCH: PARAM NAME IS ".$param->name()." EXTRA IS ".$extra->rawname()." OR ".$extra->name()."\n" if ($parmDebug);
}
}
my @constants = $curObj->constants();
foreach my $constant (@constants) {
if ($extra->can("addToConstants")) {
my $newconstant = $constant->clone();
$newconstant->apiOwner($extra);
$extra->addToConstants($newconstant);
} elsif ($extra->can("addConstant")) {
my $newconstant = $constant->clone();
$newconstant->apiOwner($extra);
$extra->addConstant($newconstant);
}
}
my @local_variables = $curObj->variables();
foreach my $variable (@local_variables) {
my $newvariable = $variable->clone();
$newvariable->apiOwner($extra);
$extra->addVariable($newvariable);
}
print STDERR "Point B6\n" if ($hangDebug);
if (length($curObj->name())) {
push(@linkobjs, \$extra);
}
}
print STDERR "Point B7 TS = $typestring\n" if ($hangDebug);
if (ref($apiOwner) ne "HeaderDoc::Header") {
if (!$apiOwner->isCOMInterface()) {
$extra->accessControl($cppAccessControlState); }
}
if ($extra != $curObj && $curtype ne "UNKNOWN" && $curObj->can("fields") && $extra->can("fields")) {
my @fields = $curObj->fields();
print STDERR "B7COPY\n" if ($localDebug);
foreach my $field (@fields) {
bless($field, "HeaderDoc::MinorAPIElement");
my $newfield = $field->clone();
$newfield->apiOwner($extra);
$extra->addToFields($newfield);
}
}
$extra->apiOwner($apiOwner);
if ($xml_output) {
$extra->outputformat("hdxml");
} else {
$extra->outputformat("html");
}
$extra->filename($filename);
$extra->fullpath($fullpath);
print STDERR "B8X blockmode=$blockmode ts=$typestring\n" if ($localDebug || $hangDebug);
my $typedefname = $parseTokens{typedefname};
my $classregexp = $parseTokens{classregexp};
my $moduleregexp = $parseTokens{moduleregexp};
if (((length($classregexp) && $typestring =~ /$classregexp/) ||
(length($moduleregexp) && $typestring =~ /$moduleregexp/) || $inClass) &&
!$inTypedef) {
print STDERR "ITSACLASS! ($extra->name)\n" if ($localDebug);
$extra->declaration($declaration);
$extra->declarationInHTML($declaration);
print STDERR "ADDING \"".$extra->name."\" TO CLASSES/PROTOCOLS/*\n" if ($localDebug);
print STDERR "RAWDEC: $declaration\n" if ($localDebug);
my $ncdeclaration = $parseTree->textTreeNC($lang, $sublang, 1);
$classType = classTypeFromFieldAndBPinfo($classKeyword, $typestring." ".$posstypes, $ncdeclaration, $fullpath, $inputCounter+$blockOffset, $sublang);
if ($classType eq "intf") {
push (@classObjects, $extra);
print STDERR "intf\n" if ($localDebug);
$apiOwner->addToProtocols($extra) if ($extra->{INSERTED} != 2);
} elsif ($classType eq "occCat") {
push (@categoryObjects, $extra);
print STDERR "occCat\n" if ($localDebug);
$apiOwner->addToCategories($extra) if ($extra->{INSERTED} != 2);
} elsif ($classType eq "occ") {
push (@classObjects, $extra);
print STDERR "occ\n" if ($localDebug);
$apiOwner->addToClasses($extra) if ($extra->{INSERTED} != 2);
} elsif ($classType eq "C" || $classType eq "cpp" || $extra->isCOMInterface() || $classType eq $lang || $classType eq $sublang) {
push (@classObjects, $extra);
print STDERR "other ($classType)\n" if ($localDebug);
$apiOwner->addToClasses($extra) if ($extra->{INSERTED} != 2);
} else {
print STDERR "Unknown class type $classType\n";
}
if ($lang eq "perl") {
$HeaderDoc::perlClassChange = $extra;
}
} elsif (($typestring =~ /$typedefname/ && length($typedefname)) || ($typestring =~ /^(class|\@class|\@interface|\@implementation|\@protocol)/)) {
if (length($declaration)) {
$extra->setDeclaration($declaration);
}
if (length($extra->name())) {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToTypedefs($extra) if ($extra->{INSERTED} != 2); }
}
} elsif ($typestring =~ /MACRO/o) {
if ($localDebug || $subparseDebug) {
print STDERR "Skipping insertion of MACRO in block mode.\n";
}
} elsif ($typestring =~ / print STDERR "SPDF[2]\n" if ($hangDebug);
$extra->setDeclaration($declaration);
print STDERR "END SPDF[2]\n" if ($hangDebug);
print STDERR "EXTRA IS $extra\n" if ($nameDebug);
print STDERR "PDEF DECL: $declaration\n" if ($nameDebug);
if ($extra !~ /HeaderDoc::PDefine/) { die("Unexpected type $extra"); }
if (($blockmode != 2) || ($extra != $curObj)) {
$apiOwner->addToPDefines($extra) if ($extra->{INSERTED} != 2);
print STDERR "Adding #define to $apiOwner in block mode. $extra == $curObj\n" if ($localDebug || $subparseDebug);
} elsif ($localDebug || $subparseDebug) {
print STDERR "Skipping insertion of #define in block mode. $extra != $curObj\n";
}
if ($extra->can('isAvailabilityMacro') && $extra->isAvailabilityMacro()) {
addAvailabilityMacro($extra->name, $extra->discussion);
}
} elsif ($typestring =~ /struct/o || $typestring =~ /union/o || ($lang eq "pascal" && $typestring =~ /record/o)) {
if ($typestring =~ /union/o) {
$extra->isUnion(1);
} else {
$extra->isUnion(0);
}
$extra->setDeclaration($declaration);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToStructs($extra) if ($extra->{INSERTED} != 2); }
} elsif ($typestring =~ /enum/o) {
$extra->declaration($declaration);
$extra->declarationInHTML($extra->getEnumDeclaration($declaration));
print STDERR "B8ENUM\n" if ($localDebug || $hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) {
print STDERR "B8ENUMINSERT apio=$apiOwner\n" if ($localDebug || $hangDebug);
$apiOwner->addToEnums($extra) if ($extra->{INSERTED} != 2); }
} elsif ($typestring =~ /\ print STDERR "SPDF[3]\n" if ($hangDebug);
$extra->setDeclaration($declaration);
print STDERR "END SPDF[3]\n" if ($hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) {
$headerObject->addToPDefines($extra);
print STDERR "Adding #define to $headerObject in block mode. $extra == $curObj\n" if ($localDebug || $subparseDebug);
} elsif ($localDebug || $subparseDebug) {
print STDERR "Skipping insertion of #define in block mode. $extra != $curObj\n";
}
if ($extra->can('isAvailabilityMacro') && $extra->isAvailabilityMacro()) {
addAvailabilityMacro($extra->name, $extra->discussion);
}
} elsif ($typestring =~ /(function|method|operator|ftmplt|callback)/o) {
if ($typestring =~ /method/) {
$extra->setDeclaration($declaration);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToMethods($extra) if ($extra->{INSERTED} != 2); }
} else {
print STDERR "SFD\n" if ($hangDebug);
if (ref($extra) ne "HeaderDoc::HeaderElement") {
$extra->setDeclaration($declaration);
}
print STDERR "END SFD\n" if ($hangDebug);
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToFunctions($extra) if ($extra->{INSERTED} != 2); }
}
if ($typestring eq "callback") {
$extra->isCallback(1);
}
if ($typestring eq "ftmplt") {
$extra->isTemplate(1);
}
} elsif ($typestring =~ /^property/o) {
$varIsConstant = 0;
$extra->isProperty(1);
$extra->declaration($declaration);
$extra->setDeclaration($declaration);
$returntype =~ s/^\s*//s;
$returntype =~ s/\s*$//s;
$extra->returntype($returntype); if (ref($apiOwner) ne "HeaderDoc::Header") {
$extra->accessControl($cppAccessControlState);
}
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToProps($extra) if ($extra->{INSERTED} != 2); }
} elsif ($typestring =~ /constant/o) {
$extra->declaration($declaration);
$extra->setDeclaration($declaration);
$returntype =~ s/^\s*//s;
$returntype =~ s/\s*$//s;
$extra->returntype($returntype);
if (length($extra->name())) {
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToConstants($extra) if ($extra->{INSERTED} != 2); }
}
} elsif ($typestring =~ /variable/o) {
$extra->declaration($declaration);
$extra->setDeclaration($declaration);
$returntype =~ s/^\s*//s;
$returntype =~ s/\s*$//s;
$extra->returntype($returntype);
if (ref($apiOwner) ne "HeaderDoc::Header") {
$extra->accessControl($cppAccessControlState);
}
if (($blockmode != 2) || ($extra != $curObj)) { $apiOwner->addToVars($extra) if ($extra->{INSERTED} != 2); }
} else {
my $linenum = $inputCounter + $blockOffset;
warn("$fullpath:$linenum: warning: Unknown typestring $typestring returned by blockParse\n");
}
print STDERR "B9 blockmode=$blockmode ts=$typestring\n" if ($localDebug || $hangDebug);
print STDERR "DOC REF: ".$extra->appleRefIsDoc()."\n" if ($nameDebug);
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 1;
my $junk = $extra->apirefSetup(1);
print STDERR "APIREF (".$extra->name()."): ".$extra->apiref()."\n" if ($nameDebug);
$HeaderDoc::ignore_apiuid_errors = $prevignore;
print "ADDED $extra to APIOWNER $apiOwner (curObj is $curObj)\n" if ($nameDebug);
}
}
if ($hangDebug) {
print STDERR "Point C\n";
print STDERR "inputCounter is $inputCounter, #inputLines is $nlines\n";
}
print STDERR "READ DECLARATION \"$declaration\"\n" if ($HeaderDoc::inputCounterDebug);
if (!$bail) {
while ($inputLines[$inputCounter] !~ /\S/o && ($inputCounter <= $nlines)) {
$inputCounter++;
print STDERR "INCREMENTED INPUTCOUNTER [9]\n" if ($HeaderDoc::inputCounterDebug);
}
if ($hangDebug) { print STDERR "Point D\n"; }
if ($curtype eq "UNKNOWN") { $curtype = $outertype; }
if ((($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/ && !($inTypedef && $outertype =~ /^(class|\@class|\@interface|\@implementation|\@protocol)/))) && (($inputCounter > $nlines) || warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "blockParse:$outertype", "18a", \%parseTokens))) {
if (!$HeaderDoc::running_test) {
warn "No matching declaration found. Last name was $curname\n";
warn buildCommentFromFields(@fields, $preAtPart, "The HeaderDoc comment that caused this was:\n")."\n";
warn "$outertype ne $curtype && $innertype ne $curtype && $posstypes !~ $curtype\n";
}
$foundMatch = 0;
print STDERR "NOMATCH: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
}
if ($hangDebug) { print STDERR "Point E\n"; }
if ($blockmode && (!$subparse)) {
while (($inputLines[$inputCounter] =~ /^\s*\/[\/*][^!]/ || $inputLines[$inputCounter] !~ /\S/s) && ($inputCounter <= $nlines)){
$inputCounter++;
}
}
if ($blockmode == 1) {
warn "next line: ".$inputLines[$inputCounter]."\n" if ($hangDebug);
print STDERR "BLOCKMODE[10] -> 2\n" if ($localDebug || $blockDebug);
$blockmode = 2;
}
if ($blockmode == 2) {
my $prevignore = $HeaderDoc::ignore_apiuid_errors;
$HeaderDoc::ignore_apiuid_errors = 1;
if (warnHDComment(\@inputLines, $inputCounter, $blockOffset, $lang, "blockMode:$outertype", "18a", \%parseTokens) == 1) {
$blockmode = 0;
print STDERR "BLOCKMODE[11] -> 0\n" if ($localDebug || $blockDebug);
warn "Block Mode Ending\n" if ($hangDebug);
}
$HeaderDoc::ignore_apiuid_errors = $prevignore;
}
print STDERR "PTCT: $posstypes =? $curtype\n" if ($localDebug || $blockDebug);
$previousInputCounter = $inputCounter;
} else {
print STDERR "BAIL: AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
last;
}
print STDERR "AT END LOOPTEST: (($blockmode || ($outertype ne $curtype && $innertype ne $curtype && $posstypes !~ /$curtype/ && !($inTypedef && $outertype =~ /^(class|\@class|\@interface|\@implementation|\@protocol)/))) && ($inputCounter <= $nlines)) || ($subparse && !$checkLineNumbers)\n" if ($localDebug || $hangDebug || $nameDebug || $nameObjDebug || $subparseDebug || $blockDebug);
print STDERR "AT END IC: $inputCounter\n" if ($HeaderDoc::inputCounterDebug);
}
print STDERR "OUT OF LOOP. Exited with blockmode = $blockmode\n" if ($localDebug || $blockDebug || $subparseDebug || $hangDebug);
if (length($blockDec)) {
$curObj->declaration($blockDec);
$curObj->declarationInHTML($blockDec);
}
if ($hangDebug) { print STDERR "Point F\n"; }
if ($curObj->can('isAvailabilityMacro') && $curObj->isAvailabilityMacro()) {
addAvailabilityMacro($curObj->name, $curObj->discussion);
}
print STDERR "Out of Block\n" if ($localDebug || $blockDebug || $hangDebug);
$inputCounter--;
print STDERR "DECREMENTED INPUTCOUNTER TO $inputCounter [11]: LINE ".$inputLines[$inputCounter]."\n" if ($HeaderDoc::inputCounterDebug);
} if ($subparse) {
$HeaderDoc::enable_cpp = $old_enable_cpp;
}
objlink(\@linkobjs);
if ($curObj) {
print "CO AT END: $curObj\n" if ($HeaderDoc::debugAllocations);
if (!$curObj->{INSERTED}) { $curObj->free(0, 1, undef); }
}
if ($curObj && $curObj->discussionLocked()) {
$curObj->unlockDiscussion();
}
return ($inputCounter, $cppAccessControlState, $classType, \@classObjects, \@categoryObjects, $blockOffset, $numcurlybraces, $foundMatch, $lang, $sublang, $hashtreecur, $hashtreeroot);
}
sub objForType
{
my $curObj = shift; my $typedefname = shift; my $typestring = shift; my $posstypes = shift; my $outertype = shift; my $curtype = shift; my $classType = shift; my $classKeyword = shift; my $declaration = shift; my $fieldref = shift; my $functionGroup = shift; my $varIsConstant = shift; my $blockmode = shift; my $inClass = shift; my $inInterface = shift; my $inTypedef = shift; my $inStruct = shift; my $fullpath = shift; my $inputCounter = shift; my $blockOffset = shift; my $lang = shift; my $sublang = shift; my $outerLocalDebug = shift; my $functionContents = shift; my $apiOwner = shift; my $subparseInputCounter = shift; my $subparseBlockOffset = shift; my $extendsClass = shift; my $implementsClass = shift; my $alwaysProcessComment = shift; my $parseTokensRef = shift; my $parserState = shift;
my $extra = undef; my $localDebug = 0;
my %parseTokens = %{$parseTokensRef};
my $filename = basename($fullpath);
print STDERR "FOR DECLARATION $declaration\n" if ($localDebug);
my $classregexp = $parseTokens{classregexp};
my $moduleregexp = $parseTokens{moduleregexp};
if ($typestring eq $outertype || !$HeaderDoc::outerNamesOnly) {
if (((length($classregexp) && $typestring =~ /$classregexp/) ||
(length($moduleregexp) && $typestring =~ /$moduleregexp/) || $inClass) && !$inTypedef && !$inStruct) {
print STDERR "blockParse returned class\n" if ($localDebug);
print STDERR "RAWDEC: $declaration\n" if ($localDebug && $outerLocalDebug);
$classType = classTypeFromFieldAndBPinfo($classKeyword, $typestring." ".$posstypes, $declaration, $fullpath, $inputCounter+$blockOffset, $sublang);
print STDERR "classtype: $classType\n" if ($localDebug);
if ($classType eq "intf") {
$extra = HeaderDoc::ObjCProtocol->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
} elsif ($classType eq "occCat") {
$extra = HeaderDoc::ObjCCategory->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
} elsif ($classType eq "occ") {
$extra = HeaderDoc::ObjCClass->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
} else {
$extra = HeaderDoc::CPPClass->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
if ($inInterface || $typestring =~ /typedef/ || $typestring =~ /struct/) {
$inInterface = 0;
$extra->isCOMInterface(1);
$extra->tocTitlePrefix('COM Interface:');
}
if ($classType eq "IDL") {
if ($typestring =~ /(module|namespace)/) {
$extra->isModule(1);
}
}
}
if ($typestring =~ /typedef/ || $outertype =~ /typedef/) {
$extra->CClass(1);
}
print STDERR "TYPESTRING IS $typestring. CCLASS IS ".$extra->CClass."\n" if ($localDebug);
$extra->group($HeaderDoc::globalGroup);
if ($parserState->{MODULE}) {
$extra->indexgroup($parserState->{MODULE}); print STDERR "MODULE: ".$parserState->{MODULE}."\n"; }
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
$extra->headerObject($HeaderDoc::headerObject);
my $class = ref($extra) || $extra;
my $superclass = $posstypes;
my $superclassfieldname = "Superclass";
if ($extra->CClass()) {
$superclassfieldname = "";
} elsif ($class =~ /HeaderDoc::ObjCCategory/) {
$superclassfieldname = "Extends Class";
} elsif ($class =~ /HeaderDoc::ObjCProtocol/) {
$superclassfieldname = "Extends Protocol";
}
if (length($superclass) && length($superclassfieldname) && (!($extra->checkShortLongAttributes($superclassfieldname))) && !$extra->CClass()) {
$extra->attribute($superclassfieldname, $superclass, 0, 1);
}
$superclassfieldname = "Extends Class";
if (length($extendsClass) && length($superclassfieldname) && (!($extra->checkShortLongAttributes($superclassfieldname))) && !$extra->CClass()) {
$extra->attribute($superclassfieldname, $extendsClass, 0, 1);
}
$superclassfieldname = "Implements Class";
if (length($implementsClass) && length($superclassfieldname) && (!($extra->checkShortLongAttributes($superclassfieldname))) && !$extra->CClass()) {
$extra->attribute($superclassfieldname, $implementsClass, 0, 1);
}
$extra->processComment($fieldref);
} elsif (($typestring =~ /^$typedefname/ && length($typedefname)) || ($typestring =~ /$classregexp/ && length($classregexp))) {
print STDERR "blockParse returned $typedefname\n" if ($localDebug);
if ($localDebug) {
foreach my $field (@{$fieldref}) {
print STDERR "FIELD $field\n";
}
}
$extra = HeaderDoc::Typedef->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
$curObj->masterEnum(1);
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^struct/o || $typestring =~ /^union/o || ($lang eq "pascal" && $typestring =~ /^record/o)) {
print STDERR "blockParse returned struct or union ($typestring)\n" if ($localDebug);
$extra = HeaderDoc::Struct->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($typestring =~ /union/o) {
$extra->isUnion(1);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^enum/o) {
print STDERR "blockParse returned enum\n" if ($localDebug);
$extra = HeaderDoc::Enum->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
if ($curtype eq "enum" || $curtype eq "typedef") {
$extra->masterEnum(0);
} else {
$extra->masterEnum(1);
}
} elsif ($typestring =~ /^MACRO/o) {
print STDERR "blockParse returned MACRO\n" if ($localDebug);
} elsif ($typestring =~ /^\ print STDERR "blockParse returned #define\n" if ($localDebug);
$extra = HeaderDoc::PDefine->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->inDefineBlock($blockmode);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^property/o) {
$varIsConstant = 0;
print STDERR "blockParse returned property\n" if ($localDebug);
$extra = HeaderDoc::Var->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
$extra->isProperty(1);
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^constant/o) {
$varIsConstant = 1;
print STDERR "blockParse returned constant\n" if ($localDebug);
$extra = HeaderDoc::Constant->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^variable/o) {
$varIsConstant = 0;
print STDERR "blockParse returned variable\n" if ($localDebug);
$extra = HeaderDoc::Var->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->group($HeaderDoc::globalGroup);
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} elsif ($typestring =~ /^(function|method|operator|ftmplt|callback)/o) {
print STDERR "blockParse returned function or method\n" if ($localDebug);
if ($typestring =~ /method/) {
$extra = HeaderDoc::Method->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->functionContents($functionContents);
if (length($functionGroup)) {
$extra->group($functionGroup);
} else {
$extra->group($HeaderDoc::globalGroup);
}
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
} else {
$extra = HeaderDoc::Function->new("LANG" => $lang, "SUBLANG" => $sublang);
$extra->apiOwner($apiOwner);
$extra->functionContents($functionContents);
if (length($functionGroup)) {
$extra->group($functionGroup);
} else {
$extra->group($HeaderDoc::globalGroup);
}
$extra->filename($filename);
$extra->fullpath($fullpath);
if (defined($subparseInputCounter)) {
$extra->linenuminblock($subparseInputCounter);
$extra->blockoffset($subparseBlockOffset);
} else {
$extra->linenuminblock($inputCounter);
$extra->blockoffset($blockOffset);
}
if ($curtype eq "UNKNOWN" || $alwaysProcessComment) {
$extra->processComment($fieldref);
}
}
if ($typestring eq "callback") {
$extra->isCallback(1);
}
if ($typestring eq "ftmplt") {
$extra->isTemplate(1);
}
} else {
my $linenum = $inputCounter + $blockOffset;
warn("$fullpath:$linenum: warning: Unknown keyword $typestring in block-parsed declaration.\n".
"This usually means that your code requires C preprocessing in order to be\n".
"valid C syntax and either C preprocessing is not enabled (-p) or the required\n".
"macros lack HeaderDoc comments. Use of the \@parseOnly tag is recommended\n".
"for these special symbols.\n");
}
} else {
print STDERR "Dropping alternate name\n" if ($localDebug);
}
return ($extra, $classType, $varIsConstant);
}
sub objlink
{
my $listref = shift;
my @list = @{$listref};
my @reflist = ();
my @masterreflist = ();
my $localDebug = 0;
my $masterobj = undef;
foreach my $objref (@list) {
my $obj = ${$objref};
bless($obj, "HeaderDoc::HeaderElement");
bless($obj, $obj->{CLASS});
if ($obj =~ /HeaderDoc::PDefine/) {
if ($obj->isBlock) {
$masterobj = $obj;
}
}
print STDERR "Obj: $obj\n" if ($localDebug);
}
print STDERR "MO: $masterobj\n" if ($localDebug);
foreach my $objref (@list) {
my $obj = ${$objref};
my $ern = $obj->name();
if ($ern =~ /\s/o && $localDebug) {
print STDERR "changed space to ctrl-d\n";
print STDERR "ref is ".$obj->apiuid()."\n";
}
$ern =~ s/\s/\cD/sgo;
if ($obj != $masterobj) {
push(@reflist, $ern." ".$obj->apiuid());
}
}
if ($masterobj) {
my $ern = $masterobj->name();
if ($ern =~ /\s/o && $localDebug) {
print STDERR "changed space to ctrl-d\n";
print STDERR "ref is ".$masterobj->apiuid()."\n";
}
$ern =~ s/\s/\cD/sgo;
@masterreflist = @reflist;
@reflist = ();
push(@reflist, $ern." ".$masterobj->apiuid());
foreach my $apiref (@masterreflist) {
if (!$masterobj->seeDupCheck($apiref) && !$masterobj->{HIDESINGLETONS}) {
$masterobj->attributelist("See Also", $apiref);
$masterobj->seeDupCheck($apiref, 1);
$masterobj->autoRelate($apiref);
}
}
}
foreach my $objref (@list) {
my $obj = ${$objref};
if ($obj != $masterobj) {
my $uid = $obj->apiuid();
if ($masterobj->{HIDESINGLETONS}) {
$obj->{HIDEDOC} = 1;
}
foreach my $apiref (@reflist) {
my $rawref = $apiref;
$rawref =~ s/.* //s;
if ($rawref ne $uid) {
if (!$obj->seeDupCheck($apiref)) {
$obj->attributelist("See Also", $apiref);
$obj->seeDupCheck($apiref, 1);
$obj->autoRelate($apiref);
}
}
}
}
}
}
sub cpp_remove($)
{
my $name = shift;
my $localDebug = 0;
print STDERR "Removing token \"$name\" from C preprocessor macros list.\n" if ($localDebug);
delete $CPP_HASH{$name};
delete $CPP_ARG_HASH{$name};
}
sub cpp_add($$)
{
my $parseTree = shift;
my $dropdeclaration = shift;
my $lang = shift;
my $sublang = shift;
my $string = $parseTree->textTree($lang, $sublang);
$string =~ s/^\/\*.*?\*\///s;
print STDERR "IN cpp_add: ADDING \"$string\"\n" if ($cppDebug || $cppAddDebug);
return cpp_add_string($string, $dropdeclaration);
}
sub cpp_add_string($$)
{
my $string = shift;
my $dropdeclaration = shift;
my $localDebug = 0;
$string =~ s/\n$//s;
my $slstring = $string;
$slstring =~ s/\\\n/ /sg;
print STDERR "cpp_add: STRING WAS $string\n" if ($cppDebug || $localDebug || $cppDebugFromToken || $cppAddDebug);
print STDERR "SLSTRING: $slstring\n" if ($localDebug || $cppDebug || $cppAddDebug);
if ($dropdeclaration && $slstring =~ s/^\s* my $name = $1;
print STDERR "Dropping declaration \"$name\"." if ($localDebug || $cppDebug);
if (exists $CPP_HASH{$name}) {
warn "Multiple definitions for $name. Using first.\n" if ($cppDebug || $warnAllMultipleDefinitions);
} else {
$CPP_HASH{$name} = "";
}
} elsif ($slstring =~ s/^(?:\/\*.*?\*\/)?\s* my $name = $1;
print STDERR "CPP ADDING FUNC-LIKE MACRO\n" if ($localDebug || $cppDebug);
print STDERR "GOT NAME $name\n" if ($localDebug || $cppDebug);
$string =~ s/^.*?\Q$name\E//s;
print STDERR "POST-STRIP: STRING IS \"$string\"\n" if ($localDebug || $cppDebug);
my @tokens = split(/(\/\/|\/\*|\*\/|\W)/, $string);
my $firstpart = "";
my $lastpart = "";
my $fpdone = 0;
my $lasttoken = "";
my $inChar = 0; my $inString = 0; my $inComment = 0; my $inSLC = 0;
my $inParen = 0;
foreach my $token (@tokens) {
if (!$token) { next; };
print STDERR "TOK: $token LAS: $lasttoken ICH: $inChar ICO: $inComment ISL: $inSLC IST: $inString\n" if ($localDebug || $cppDebug);
if (!$fpdone) {
if (!$inParen && $token =~ /\w/) {
$lastpart .= $token;
$fpdone = 1;
next;
} elsif ($token eq "//" && !$inComment) {
$inSLC = 1;
$token = "/*";
$lastpart .= $token;
$fpdone = 1;
next;
} elsif ($token eq "/*" && !$inChar && !$inString && !$inSLC) {
$inComment = 1;
} elsif ($token eq "*/" && !$inChar && !$inString && !$inSLC) {
$inComment = 0;
} elsif ($token eq '\\') {
if ($lasttoken eq '\\') { $lasttoken = ""; }
else { $lasttoken = $token; }
} elsif ($token eq '"') {
if ($lasttoken ne '\\') {
if (!$inChar && !$inComment && !$inSLC) {
$inString = !$inString;
}
}
$lasttoken = $token;
} elsif ($token eq "'") {
if ($lasttoken ne '\\') {
if (!$inString && !$inComment && !$inSLC) {
$inChar = !$inChar;
}
}
$lasttoken = $token;
} elsif (!$inChar && !$inString && !$inComment && !$inSLC) {
if ($token eq "(") {
$inParen++;
} elsif ($token eq ")") {
$inParen--;
} elsif ($token =~ /\s/) {
if (!$inParen) {
$fpdone = 1;
}
}
$lasttoken = $token;
}
$firstpart .= $token;
} else {
print STDERR "TAILTOKEN: \"$token\"\n" if ($cppDebug);
if ($token eq "//" && !$inComment) {
$inSLC = 1;
$token = "/*";
} elsif ($token eq "/*" && !$inChar && !$inString && !$inSLC) {
$inComment = 1;
} elsif ($token eq "*/" && !$inChar && !$inString && !$inSLC) {
$inComment = 0;
}
$lastpart .= $token;
}
}
$firstpart =~ s/^\(//s;
$firstpart =~ s/\s*$//s;
$firstpart =~ s/\)$//s;
if ($inSLC) {
$lastpart .= "*/";
}
print STDERR "FP: \"$firstpart\"\nLP: \"$lastpart\"\nFPLPEND\n" if ($cppDebug || $localDebug);
if ($lastpart) {
my @lines = split(/[\r\n]/, $lastpart);
my $lastline = pop(@lines);
my $definition = "";
foreach my $line (@lines) {
if ($line) {
$line =~ s/\\\s*$//s;
$line .= "\n";
$definition .= $line;
}
}
print STDERR "LL: \"$lastline\"\n" if ($cppDebug);
push(@lines, $lastline);
$definition .= "$lastline";
print STDERR "ADDING NAME=\"$name\" ARGS=\"$firstpart\" DEFINITION=\"$definition\"\n" if ($cppDebug);
if (exists $CPP_HASH{$name}) {
warn "Multiple definitions for $name. Using first.\n" if (($cppDebug || $warnAllMultipleDefinitions) && $HeaderDoc::enable_cpp);
} else {
$CPP_HASH{$name} = $definition;
if (length($firstpart)) {
$CPP_ARG_HASH{$name} = $firstpart;
}
}
} else {
if (exists $CPP_HASH{$name}) {
warn "Multiple definitions for $name. Using first.\n" if ($cppDebug || $warnAllMultipleDefinitions);
} else {
$CPP_HASH{$name} = "";
if (length($firstpart)) {
$CPP_ARG_HASH{$name} = $firstpart;
}
}
}
} elsif ($slstring =~ s/^\s* my $name = $1;
if (exists $CPP_HASH{$name}) {
warn "Multiple definitions for $name. Using first.\n" if ($cppDebug || $warnAllMultipleDefinitions);
} else {
$CPP_HASH{$name} = "";
}
} else {
warn "COWARDLY REFUSING TO HANDLE \"$string\".\n" if ($HeaderDoc::enable_cpp);
}
}
sub cpp_add_cl
{
my $name = shift;
my $value = shift;
$CPP_HASH{$name} = $value;
}
sub cpp_preprocess
{
my $part = shift;
my $linenum = shift;
my $hasargs = 0;
my $count = 0;
if ($HeaderDoc::enable_cpp > 0) {
print STDERR "CPP ENABLE\n" if ($cppDebug > 1);
foreach my $hashhashref (@HeaderDoc::cppHashList) {
print STDERR "HASHREFCHECK\n" if ($cppDebug > 1);
my $hashref = $hashhashref->{HASHREF};
print STDERR "HASHREF: $hashref\n" if ($cppDebug);
if (!$hashref) {
warn "Empty hashref object!\n";
next;
}
my %hash = %{$hashhashref->{HASHREF}};
if ($linenum <= $hashhashref->{LINENUM}) {
print STDERR "Skiping hash $hashhashref->{FILENAME}. Line not reached.\n" if ($cppDebug);
next;
}
print STDERR "COUNT: $count\nNARGHASHES: ".scalar(@HeaderDoc::cppArgHashList)."\n" if ($cppDebug);
print STDERR "NHASHES: ".scalar(@HeaderDoc::cppHashList)."\n" if ($cppDebug);
my $arghashref = $HeaderDoc::cppArgHashList[$count++];
my %arghash = %{$arghashref};
my $altpart = $hash{$part};
my $exists = defined $hash{$part};
if ($exists) {
print STDERR "EXTHASH FOUND NAME=\"$part\" REPLACEMENT=\"$altpart\"\n" if ($cppDebug);
if ($arghash{$part}) { $hasargs = 1; }
print STDERR "HASARGS: $hasargs\n" if ($cppDebug);
return ($altpart, $hasargs, $arghash{$part});
}
}
my $altpart = $CPP_HASH{$part};
my $exists = exists $CPP_HASH{$part};
if ($exists) {
print STDERR "FOUND NAME=\"$part\" REPLACEMENT=\"$altpart\"\n" if ($cppDebug);
if (exists($CPP_ARG_HASH{$part})) { $hasargs = 1; }
print STDERR "HASARGS: $hasargs\n" if ($cppDebug);
return ($altpart, $hasargs, $CPP_ARG_HASH{$part});
}
} else {
print STDERR "C preprocessing is disabled.\n" if ($cppDebug);
}
if ($HeaderDoc::enable_cpp != -1) {
print STDERR "Checking token \"$part\" for ignored macros\n" if ($cppDebug);
my $altpart = $HeaderDoc::perHeaderIgnoreFuncMacros{$part};
if ($altpart && length($altpart)) {
print STDERR "Found token \"$part\" among ignored macros\n" if ($cppDebug);
$hasargs = 2;
$part = "";
}
}
return ($part, $hasargs, "");
}
sub getAndClearCPPHash
{
my %newhash = %CPP_HASH;
my %newarghash = %CPP_ARG_HASH;
%CPP_HASH = ();
%CPP_ARG_HASH = ();
return (\%newhash, \%newarghash);
}
sub setCPPHashes
{
my $cpphashref = shift;
my $cpparghashref = shift;
%CPP_HASH = %{$cpphashref};
%CPP_ARG_HASH = %{$cpparghashref};
}
sub cpp_argparse
{
my $name = shift;
my $linenum = shift;
my $arglistref = shift;
my @arglist = ();
if ($arglistref) { @arglist = @{$arglistref}; }
my %arghash = ();
if ($cppDebug) {
print STDERR "CPP_ARGPARSE: NM $name ARGS:\n";
foreach my $arg (@arglist) {
print STDERR "$arg\n";
$arg->printTree();
}
print STDERR "ENDARGS\n";
}
print STDERR "SEARCHING FOR NAME \"$name\"\n" if ($cppDebug);
my ($newtoken, $has_args, $pattern) = cpp_preprocess($name, $linenum);
print STDERR "PATTERN WAS \"$pattern\"\n" if ($cppDebug);
my @parts = split(/,/, $pattern);
my $count = 0;
while ($count < scalar(@parts)) {
my $part = $parts[$count];
print STDERR "ORIGPART WAS $part\n" if ($cppDebug);
$part =~ s/\s//sg;
if (!$arglist[$count]) {
warn "Not enough arguments to macro $name\n";
} else {
print STDERR "CALLING ON ".$arglist[$count]."\n" if ($cppDebug);
$arghash{$part} = cpp_subparse($arglist[$count]); print STDERR "PART \"$part\" VALUE: \"".$arghash{$part}."\"\n" if ($cppDebug)
}
print STDERR "POINTS TO $arghash{$part}\n" if ($cppDebug);
$count++;
}
my $retstring = "";
my @ntparts = split(/(\W)/, $newtoken);
my $lastpart = "";
my $poundcount = 0;
foreach my $part (@ntparts) {
if (length($part)) {
print STDERR "PART WAS $part\n" if ($cppDebug);
if ($part eq "#") {
$poundcount++;
} else {
my $curpart = "";
if (defined($arghash{$part})) {
print STDERR "Inserting argument (".$arghash{$part}.") for $part\n" if ($cppDebug);
$curpart = (($poundcount == 1) ? "\"" : "").$arghash{$part}.(($poundcount == 1) ? "\"" : "");
} else {
print STDERR "No arguments found for $part\n" if ($cppDebug);
$curpart = (($poundcount == 1) ? "\"" : "").$part.(($poundcount == 1) ? "\"" : "");
}
if ($poundcount < 2) {
$retstring .= $lastpart;
$lastpart = $curpart;
} else {
$lastpart .= $curpart;
}
$poundcount = 0;
}
}
}
$retstring .= $lastpart;
return $retstring;
}
sub cpp_subparse($)
{
my $tree = shift;
my ($newtoken, $has_args, $tempstring) = cpp_preprocess($tree->token(), $tree->linenum());
if ($cppDebug) {
print STDERR "SUBPARSE: ARGS: $has_args\n";
$tree->dbprint();
print STDERR "END SUBPARSE DUMP\n";
}
if ($has_args) {
my $name = $tree->token();
my $paren = $tree->next();
if (!$paren) { return; }
if ($paren->token() =~ /\(/) {
my @parts = ();
my $fc = $paren->firstchild();
my $subparsetop = HeaderDoc::ParseTree->new();
my $subparsecur = $subparsetop;
while ($fc) { my $fct = $fc->token();
print STDERR "FCT: $fct\n" if ($cppDebug);
if ($fct eq ',') {
print STDERR "PUSH\n" if ($cppDebug);
push(@parts, $subparsetop);
$subparsetop = $subparsecur = HeaderDoc::ParseTree->new();
} else {
print STDERR "NEXT\n" if ($cppDebug);
$subparsecur = $subparsecur->next(HeaderDoc::ParseTree->new());
$subparsecur->token($fct);
}
$fc = $fc->next();
}
push(@parts, $subparsetop);
print STDERR "CALLING ARGPARSE FROM cpp_subparse().\n" if ($cppDebug);
my $ap = cpp_argparse($name, $tree->linenum(), \@parts); print STDERR "Changed token from $tree (\"".$tree->token."\") to \"$ap\"\n" if ($cppDebug);
$tree->token($ap);
$paren->token("");
$paren->firstchild(undef);
if ($paren->next->token ne ")") {
warn("Tree structure problem (cpp_subparse point 1). Please file a bug.\n");
} else {
$paren->next->token("");
}
} else {
warn("Tree structure problem (cpp_subparse point 2). Please file a bug.\n");
}
} else {
$tree->token($newtoken);
}
my $fc = $tree->firstchild();
if ($fc) {
cpp_subparse($fc);
}
my $n = $tree->next();
if ($n) {
cpp_subparse($n);
}
return $tree->textTree();
}
sub cppsupers
{
my $string = shift;
my $lang = shift;
my $sublang = shift;
my $localDebug = 0;
my @parts = split(/(\W)/, $string);
my $superlist = "";
my $cursuper = "";
my %parseTokens = %{parseTokens($lang, $sublang)};
my $accessregexp = $parseTokens{accessregexp};
my $inTemplate = 0;
foreach my $part (@parts) {
if ($part eq "<") {
$inTemplate = 1;
$cursuper .= $part;
} elsif ($part eq ">") {
$inTemplate = 0;
$cursuper .= $part;
} elsif (!$inTemplate && $part eq ",") {
$superlist .= "\cA".$cursuper;
$cursuper = "";
} elsif ($part =~ /\cA/) {
} elsif (!length($accessregexp) || $part !~ /$accessregexp/) {
$cursuper .= $part;
}
}
$superlist .= "\cA".$cursuper;
$superlist =~ s/^\cA//s;
if ($lang eq "tcl" || $sublang eq "tcl") {
$superlist =~ s/^\s*{//s;
$superlist =~ s/}\s*$//s;
}
print STDERR "SUPERLIST IS $superlist\n" if ($localDebug);
return $superlist;
}
sub decomment
{
my $string = shift;
my $newstring = "";
my @lines = split(/\n/, $string);
foreach my $line (@lines) {
$line =~ s/\/\/.*$//g;
if (length($line)) {
$newstring .= $line;
}
}
$newstring =~ s/\/\*.*?\*\///sg;
return $newstring;
}
sub buildCommentFromFields
{
my @fields = shift;
my $preAtPart = shift;
my $message = shift;
my $string = "";
my $first = 1;
my $at = "";
foreach my $field (@fields) {
$string .= $at.$field."\n";
if ($first && length($preAtPart)) {
$string .= " ".$preAtPart."\n";
$first = 0;
}
$at = "\@";
}
if ($string =~ /\S/) {
if ($string =~ /^\s*\/\*/s) {
$string .= " */\n";
}
$string = "$message\n".$string;
}
return $string;
}
sub macroRegexpFromList
{
my $nameref = shift;
my $onlywithpound = shift;
my %names = %{$nameref};
my $regexpstring = "";
my $pipe = "";
my $lparen = "(";
foreach my $name (keys %names) {
if (!$onlywithpound) {
$regexpstring .= $lparen.$pipe.$name;
$pipe = "|"; $lparen = "";
} elsif ($onlywithpound == 1) {
if ($name =~ /^ my $temp = $name;
$temp =~ s/^ $regexpstring .= $lparen.$pipe.$temp;
$pipe = "|"; $lparen = "";
}
} elsif ($onlywithpound == 2) {
if ($name !~ /^ $regexpstring .= $lparen.$pipe.$name;
$pipe = "|"; $lparen = "";
}
}
}
if ($regexpstring ne "") { $regexpstring .= ")"; }
return $regexpstring;
}
sub empty_comment
{
my @fields = shift;
if (!scalar(@fields)) { return 1; }
if (scalar(@fields) == 1 && $fields[0] =~ /^\s*\/\*\!\s*$/) { return 1; }
return 0;
}
sub cppHashMerge
{
my $root = shift;
my $curhashobj = shift;
my $cpphashref = shift;
my $cpparghashref = shift;
my $token = shift;
my $localDebug = 0;
print STDERR "IN cppHashMerge WITH TOKEN: $token\n" if ($localDebug);
if (!$root) {
$root = HeaderDoc::HashObject->new();
}
if (!$curhashobj) {
$curhashobj = $root;
}
print STDERR "GOING IN:\n" if ($localDebug);
$root->dbprint() if ($localDebug);
my $hashret = ();
my $arghashret = ();
SWITCH: {
($token =~ / print STDERR "IF CASE\n" if ($localDebug);
($hashret, $arghashret) = $curhashobj->cppHashNodeSetHashes($cpphashref, $cpparghashref);
$curhashobj = $curhashobj->cppHashNodeNewChild($token);
last;
};
($token =~ / print STDERR "ELSE CASE\n" if ($localDebug);
$curhashobj-> cppHashNodeSetHashes($cpphashref, $cpparghashref);
$curhashobj = $curhashobj->cppHashNodeNewSibling($token);
($hashret, $arghashret) = $curhashobj->cppHashNodeResetToParent();
last;
};
($token =~ / print STDERR "ELIF CASE\n" if ($localDebug);
$curhashobj->cppHashNodeSetHashes($cpphashref, $cpparghashref);
$curhashobj = $curhashobj->cppHashNodeNewSibling($token);
($hashret, $arghashret) = $curhashobj->cppHashNodeResetToParent();
last;
};
($token =~ / print STDERR "ENDIF CASE\n" if ($localDebug);
$curhashobj->cppHashNodeSetHashes($cpphashref, $cpparghashref);
($curhashobj, $hashret, $arghashret) = $curhashobj->cppHashNodePop();
last;
};
{
print STDERR "COMING OUT:\n" if ($localDebug);
$root->dbprint() if ($localDebug);
return ($cpphashref, $cpparghashref, $root, $curhashobj);
};
}
print STDERR "COMING OUT:\n" if ($localDebug);
$root->dbprint() if ($localDebug);
return ($hashret, $arghashret, $root, $curhashobj);
}
sub configureAccessControlStateForClass
{
my $parserState = shift;
my $lang = $parserState->{lang};
if ($lang eq "php") {
$HeaderDoc::AccessControlState = "public";
} elsif ($lang eq "java") {
$HeaderDoc::AccessControlState = "package-private";
} elsif ($lang eq "C") {
if ($parserState->{classIsObjC} || ($parserState->{lang} eq "IDL" && $HeaderDoc::idl_language eq "occ")) {
$HeaderDoc::AccessControlState = "private";
if ($parserState->{inProtocol}) {
$HeaderDoc::OptionalOrRequired = "\@required"; }
} else {
$HeaderDoc::AccessControlState = "protected";
}
}
}
1;