package HeaderDoc::BlockParse;
BEGIN {
foreach (qw(Mac::Files)) {
$MOD_AVAIL{$_} = eval "use $_; 1";
}
}
use Exporter;
foreach (qw(Mac::Files Mac::MoreFiles)) {
eval "use $_";
}
$VERSION = 1.02;
@ISA = qw(Exporter);
@EXPORT = qw(blockParse nspaces);
use HeaderDoc::Utilities qw(findRelativePath safeName getAPINameAndDisc convertCharsForFileMaker printArray printHash quote parseTokens isKeyword);
use strict;
use vars qw($VERSION @ISA);
$VERSION = '1.20';
sub peek
{
my $ref = shift;
my @stack = @{$ref};
my $tos = pop(@stack);
push(@stack, $tos);
return $tos;
}
sub peekmatch
{
my $ref = shift;
my $filename = shift;
my $linenum = shift;
my @stack = @{$ref};
my $tos = pop(@stack);
push(@stack, $tos);
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 "]";
};
{
warn "$filename:$linenum:Unknown regexp delimiter \"$tos\". Please file a bug.\n";
return $tos;
};
}
}
sub blockParse
{
my $filename = shift;
my $fileoffset = shift;
my $inputLinesRef = shift;
my $inputCounter = shift;
my $argparse = shift;
my $ignoreref = shift;
my $perheaderignoreref = shift;
my $keywordhashref = shift;
my $case_sensitive = shift;
my @inputLines = @{$inputLinesRef};
my $declaration = "";
my $publicDeclaration = "";
my $localDebug = 0;
my $listDebug = 0;
my $parseDebug = 0;
my $sodDebug = 0;
my $valueDebug = 0;
my $parmDebug = 0;
my $cbnDebug = 0;
my $macroDebug = 0;
my $apDebug = 0;
my $tsDebug = 0;
my $treeDebug = 0;
my $ilcDebug = 0;
my $regexpDebug = 0;
my $typestring = "";
my $continue = 1; my $parsedParamParse = 0; my @parsedParamList = (); my @pplStack = (); my @freezeStack = (); my $stackFrozen = 0; my $lang = $HeaderDoc::lang;
my $perl_or_shell = 0;
my $sublang = $HeaderDoc::sublang;
my $callback_typedef_and_name_on_one_line = 1; my $returntype = "";
my $freezereturn = 0; my $treeNest = 0; my $treepart = ""; my $availability = ""; my $seenTilde = 0;
if ($argparse && $tsDebug) { $tsDebug = 0; }
my $treeTop = HeaderDoc::ParseTree->new(); my $treeCur = $treeTop; my $treeSkip = 0; my $treePopTwo = 0; my $treePopOnNewLine = 0; my @treeStack = ();
if ($argparse && $apDebug) {
$localDebug = 1;
$listDebug = 1;
$parseDebug = 1;
$sodDebug = 1;
$valueDebug = 1;
$parmDebug = 1;
$cbnDebug = 1;
$macroDebug = 1;
$tsDebug = 1;
$treeDebug = 1;
$ilcDebug = 1;
$regexpDebug = 1;
}
if ($argparse && ($localDebug || $apDebug)) {
print "ARGPARSE MODE!\n";
print "IPC: $inputCounter\nNLINES: ".$ }
my $inComment = 0;
my $inInlineComment = 0;
my $inString = 0;
my $inChar = 0;
my $inTemplate = 0;
my @braceStack = ();
my $inOperator = 0;
my $inPrivateParamTypes = 0; my $onlyComments = 1; my $inMacro = 0;
my $inMacroLine = 0; my $seenMacroPart = 0; my $macroNoTrunc = 1; my $inBrackets = 0; my $inPType = 0; my $inRegexp = 0; my $inRegexpTrailer = 0; my $ppSkipOneToken = 0;
my $regexppattern = ""; my $singleregexppattern = ""; my $regexpcharpattern = ""; my @regexpStack = ();
my ($sotemplate, $eotemplate, $operator, $soc, $eoc, $ilc, $sofunction,
$soprocedure, $sopreproc, $lbrace, $rbrace, $unionname, $structname,
$typedefname, $varname, $constname, $structisbrace, $macronameref)
= parseTokens($lang, $sublang);
if ($lang eq "perl" || $lang eq "shell") {
$perl_or_shell = 1;
if ($lang eq "perl") {
$regexpcharpattern = '\\{|\\#\\(|\\/|\\\'|\\"|\\<|\\[|\\`';
$regexppattern = "qq|qr|qx|qw|q|m|s|tr|y";
$singleregexppattern = "qq|qr|qx|qw|q|m";
}
}
my $pascal = 0;
if ($lang eq "pascal") { $pascal = 1; }
my $lastsymbol = "";
my $name = ""; my $callbackNamePending = 0; my $callbackName = ""; my $callbackIsTypedef = 0;
my $namePending = 0; my $basetype = ""; my $posstypes = ""; my $posstypesPending = 1; my $sodtype = ""; my $sodname = ""; my $sodclass = "";
my $simpleTypedef = 0; my $simpleTDcontents = ""; my $seenBraces = 0; my $kr_c_function = 0; my $kr_c_name = "";
my $lastchar = ""; my $lastnspart = ""; my $lasttoken = ""; my $startOfDec = 1; my $prespace = 0; my $prespaceadjust = 0; my $scratch = ""; my $curline = ""; my $curstring = ""; my $continuation = 0; my $forcenobreak = 0; my $occmethod = 0; my $occspace = 0; my $occmethodname = ""; my $preTemplateSymbol = ""; my $preEqualsSymbol = ""; my $valuepending = 0; my $value = ""; my $parsedParam = ""; my $postPossNL = 0;
my $nlines = $ while ($continue && ($inputCounter <= $nlines)) {
my $line = $inputLines[$inputCounter++];
my @parts = ();
$line =~ s/^\s*//go;
$line =~ s/\s*$//go;
$line .= "\n";
if ($lang eq "perl" || $lang eq "shell") {
@parts = split(/("|'|\#|\{|\}|\(|\)|\s|;|\\|\W)/, $line);
} else {
@parts = split(/("|'|\/\/|\/\*|\*\/|::|==|<=|>=|!=|\<\<|\>\>|\{|\}|\(|\)|\s|;|\\|\W)/, $line);
}
$inInlineComment = 0;
print "inInlineComment -> 0\n" if ($ilcDebug);
# warn("line $inputCounter\n");
if ($localDebug) {foreach my $partlist (@parts) {print "PARTLIST: $partlist\n"; }}
# This block 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
push(@parts, "BOGUSBOGUSBOGUSBOGUSBOGUS");
my $part = "";
foreach my $nextpart (@parts) {
$treeSkip = 0;
$treePopTwo = 0;
print "MYPART: $part\n" if ($localDebug);
$forcenobreak = 0;
if ($nextpart eq "\r") { $nextpart = "\n"; }
if ($localDebug && $nextpart eq "\n") { print "NEXTPART IS NEWLINE!\n"; }
if ($localDebug && $part eq "\n") { print "PART IS NEWLINE!\n"; }
if ($nextpart ne "\n" && $nextpart =~ /\s/o) {
$nextpart = " ";
}
if ($part ne "\n" && $part =~ /\s/o && $nextpart ne "\n" &&
$nextpart =~ /\s/o) {
next;
}
print "PART IS \"$part\"\n" if ($localDebug);
print "CURLINE IS \"$curline\"\n" if ($localDebug);
if (!length($nextpart)) {
print "SKIP NP\n" if ($localDebug);
next;
}
if (!length($part)) {
print "SKIP PART\n" if ($localDebug);
$part = $nextpart;
next;
}
if ($parseDebug) {
print "PART: $part, type: $typestring, inComment: $inComment, inInlineComment: $inInlineComment, inChar: $inChar.\n" if ($localDebug);
print "PART: bracecount: " . scalar(@braceStack) . "\n";
print "PART: inString: $inString, callbackNamePending: $callbackNamePending, namePending: $namePending, lastsymbol: $lastsymbol, lasttoken: $lasttoken, lastchar: $lastchar, SOL: $startOfDec\n" if ($localDebug);
print "PART: sodclass: $sodclass sodname: $sodname\n";
print "PART: posstypes: $posstypes\n";
print "PART: seenBraces: $seenBraces inRegexp: $inRegexp\n";
print "PART: seenTilde: $seenTilde\n";
print "PART: CBN: $callbackName\n";
print "PART: regexpStack is:";
foreach my $token (@regexpStack) { print " $token"; }
print "\n";
print "PART: npplStack: ".scalar(@pplStack)." nparsedParamList: ".scalar(@parsedParamList)." nfreezeStack: ".scalar(@freezeStack)." frozen: $stackFrozen\n";
print "PART: inMacro: $inMacro treePopOnNewLine: $treePopOnNewLine\n";
print "length(declaration) = " . length($declaration) ."; length(curline) = " . length($curline) . "\n";
} elsif ($tsDebug || $treeDebug) {
print "BPPART: $part\n";
}
my $tempavail = ignore($part, $ignoreref, $perheaderignoreref);
if ($tempavail && ($tempavail ne "1")) {
$availability = $tempavail;
}
$treepart = "";
SWITCH: {
(($inMacro == 1) && ($part eq "define")) && do{
$inMacro = 3;
$sodname = "";
my $pound = $treeCur->token();
if ($pound eq "$sopreproc") {
$treeNest = 2;
$treePopOnNewLine = 2;
$pound .= $part;
$treeCur->token($pound);
}
last SWITCH;
};
(($inMacro == 1) && ($part =~ /(if|ifdef|ifndef|endif|else|pragma|import|include)/o)) && do {
$inMacro = 4;
$sodname = "";
my $pound = $treeCur->token();
if ($pound eq "$sopreproc") {
$treeNest = 2;
$treePopOnNewLine = 1;
$pound .= $part;
$treeCur->token($pound);
if ($part eq "endif") {
$treeNest = 0;
$treeSkip = 1;
}
}
last SWITCH;
};
(($inMacroLine == 1) && ($part =~ /(if|ifdef|ifndef|endif|else|pragma|import|include|define)/o)) && do {
my $pound = $treeCur->token();
if ($pound eq "$sopreproc") {
$pound .= $part;
$treeCur->token($pound);
if ($part =~ /define/o) {
$treeNest = 2;
$treePopOnNewLine = 2;
} elsif ($part eq "endif") {
$treeNest = 0;
$treeSkip = 1;
} else {
$treeNest = 2;
$treePopOnNewLine = 1;
}
}
last SWITCH;
};
($inMacro == 1) && do {
$inMacro = 2;
last SWITCH;
};
($inMacro > 1 && $part ne "//") && do {
print "PART: $part\n" if ($macroDebug);
if ($seenMacroPart && $HeaderDoc::truncate_inline) {
if (!scalar(@braceStack)) {
if ($part =~ /\s/o && $macroNoTrunc == 1) {
$macroNoTrunc = 0;
} elsif ($part =~ /[\{\(]/o) {
if (!$macroNoTrunc) {
$seenBraces = 1;
}
} else {
$macroNoTrunc = 2;
}
}
}
if ($part =~ /[\{\(]/o) {
push(@braceStack, $part);
print "PUSH\n" if ($macroDebug);
} elsif ($part =~ /[\}\)]/o) {
if ($part ne peekmatch(\@braceStack, $filename, $inputCounter)) {
warn("$filename:$inputCounter:Initial braces in macro name do not match.\nWe may have a problem.\n");
}
pop(@braceStack);
print "POP\n" if ($macroDebug);
}
if ($part =~ /\S/o) {
$seenMacroPart = 1;
$lastsymbol = $part;
if (($sodname eq "") && ($inMacro == 3)) {
print "DEFINE NAME IS $part\n" if ($macroDebug);
$sodname = $part;
}
}
$lastchar = $part;
last SWITCH;
};
(length($regexppattern) && $part =~ /^($regexppattern)$/ && !($inRegexp || $inRegexpTrailer || $inString || $inComment || $inInlineComment || $inChar)) && do {
my $match = $1;
print "REGEXP WITH PREFIX\n" if ($regexpDebug);
if ($match =~ /^($singleregexppattern)$/) {
$inRegexp = 2;
} else {
$inRegexp = 4;
}
last SWITCH;
}; (($inRegexp || $lastsymbol eq "~") && (length($regexpcharpattern) && $part =~ /^($regexpcharpattern)$/ && (!scalar(@regexpStack) || $part eq peekmatch(\@regexpStack, $filename, $inputCounter)))) && do {
print "REGEXP?\n" if ($regexpDebug);
if (!$inRegexp) {
$inRegexp = 2;
}
if ($lasttoken eq "\\") {
$lasttoken = $part;
$lastsymbol = $part;
next SWITCH;
}
print "REGEXP POINT A\n" if ($regexpDebug);
$lasttoken = $part;
$lastsymbol = $part;
if ($part eq "#" &&
((scalar(@regexpStack) != 1) ||
(peekmatch(\@regexpStack, $filename, $inputCounter) ne "#"))) {
if ($nextpart =~ /^\s/o) {
next SWITCH;
}
}
print "REGEXP POINT B\n" if ($regexpDebug);
if (!scalar(@regexpStack)) {
push(@regexpStack, $part);
$inRegexp--;
} else {
my $match = peekmatch(\@regexpStack, $filename, $inputCounter);
my $tos = pop(@regexpStack);
if (!scalar(@regexpStack) && ($match eq $part)) {
$inRegexp--;
if ($inRegexp == 2 && $tos eq "/") {
$inRegexp--;
}
if ($inRegexp) {
push(@regexpStack, $tos);
}
} elsif (scalar(@regexpStack) == 1) {
push(@regexpStack, $tos);
if ($tos =~ /['"`]/o) {
# these don't interpolate.
next SWITCH;
}
} else {
push(@regexpStack, $tos);
if ($tos =~ /['"`]/o) {
# these don't interpolate.
next SWITCH;
}
push(@regexpStack, $part);
}
}
print "REGEXP POINT C\n" if ($regexpDebug);
if (!$inRegexp) {
$inRegexpTrailer = 2;
}
last SWITCH;
};
($part eq "$sopreproc") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if ($onlyComments) {
print "inMacro -> 1\n" if ($macroDebug);
$inMacro = 1;
} elsif ($curline =~ /^\s*$/o) {
$inMacroLine = 1;
print "IML\n" if ($localDebug);
} elsif ($postPossNL) {
print "PRE-IML \"$curline\"\n" if ($localDebug || $macroDebug);
$treeCur = $treeCur->addSibling("\n", 0);
bless($treeCur, "HeaderDoc::ParseTree");
$inMacroLine = 1;
$postPossNL = 0;
}
}
};
($part eq "$sofunction" || $part eq "$soprocedure") && do {
$sodclass = "function";
print "K&R C FUNCTION FOUND [1].\n" if ($localDebug);
$kr_c_function = 1;
$typestring = "function";
$startOfDec = 0;
$namePending = 1;
print "namePending -> 1 [1]\n" if ($parseDebug);
last SWITCH;
};
($part =~ /\~/o && $lang eq "C" && $sublang eq "cpp") && do {
print "TILDE\n" if ($localDebug);
$seenTilde = 2;
$lastchar = $part;
$onlyComments = 0;
last SWITCH;
};
($part =~ /[-+]/o && $declaration !~ /\S/o && $curline !~ /\S/o) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
print "OCCMETHOD\n" if ($localDebug);
$occmethod = 1;
$lastchar = $part;
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
if (!$seenBraces) { $treeNest = 1;
$treePopTwo = 1;
}
}
last SWITCH;
};
($part =~ /[\n\r]/o) && do {
$treepart = $part;
if ($inRegexp) {
warn "$filename:$inputCounter:multi-line regular expression\n";
}
print "NLCR\n" if ($tsDebug || $treeDebug || $localDebug);
if ($lastchar !~ /[\,\;\{\(\)\}]/o && $nextpart !~ /[\{\}\(\)]/o) {
if ($lastchar ne "*/" && $nextpart ne "/*") {
if (!$inMacro && !$inMacroLine && !$treePopOnNewLine) {
print "NL->SPC\n" if ($localDebug);
$part = " ";
print "LC: $lastchar\n" if ($localDebug);
print "NP: $nextpart\n" if ($localDebug);
$postPossNL = 2;
} else {
$inMacroLine = 0;
}
}
}
if ($treePopOnNewLine < 0) {
$treePopOnNewLine = 0 - $treePopOnNewLine;
$treeCur = $treeCur->addSibling($treepart, 0);
bless($treeCur, "HeaderDoc::ParseTree");
$treeSkip = 1;
$treeCur = pop(@treeStack);
print "TSPOP [1]\n" if ($tsDebug || $treeDebug);
if (!$treeCur) {
$treeCur = $treeTop;
warn "$filename:$inputCounter:Attempted to pop off top of tree\n";
}
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($treePopOnNewLine == 1 || ($treePopOnNewLine && $lastsymbol ne "\\")) {
$treeCur = $treeCur->addSibling($treepart, 0);
bless($treeCur, "HeaderDoc::ParseTree");
$treeSkip = 1;
$treeCur = pop(@treeStack);
print "TSPOP [1a]\n" if ($tsDebug || $treeDebug);
if (!$treeCur) {
$treeCur = $treeTop;
warn "$filename:$inputCounter:Attempted to pop off top of tree\n";
}
bless($treeCur, "HeaderDoc::ParseTree");
$treePopOnNewLine = 0;
}
next SWITCH;
};
($part eq $sotemplate && !$seenBraces) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
print "inTemplate -> 1\n" if ($localDebug);
print "SBS: " . scalar(@braceStack) . ".\n" if ($localDebug);
$inTemplate = 1;
if (!scalar(@braceStack)) {
$preTemplateSymbol = $lastsymbol;
}
$lastsymbol = "";
$lastchar = $part;
$onlyComments = 0;
push(@braceStack, $part); pbs(@braceStack);
if (!$seenBraces) { $treeNest = 1;
}
print "onlyComments -> 0\n" if ($macroDebug);
}
last SWITCH;
};
($part eq $eotemplate && !$seenBraces) && do {
if (!($inString || $inComment || $inInlineComment || $inChar) && (!scalar(@braceStack) || $inTemplate)) {
if ($inTemplate) {
print "inTemplate -> 0\n" if ($localDebug);
$inTemplate = 0;
$lastsymbol = "";
$lastchar = $part;
$curline .= " ";
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
my $top = pop(@braceStack);
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [2]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($top ne "$sotemplate") {
warn("$filename:$inputCounter:Template (angle) brackets do not match.\nWe may have a problem.\n");
}
}
last SWITCH;
};
($part eq ":") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if ($occmethod) {
$name = $lastsymbol;
$occmethodname .= "$lastsymbol:";
if ($occmethod == 1) {
$occmethod = 2;
if (!$prespace) { $prespaceadjust = 4; }
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
} else {
if ($lang eq "C" && $sublang eq "cpp") {
if (!scalar(@braceStack) && $sodclass eq "function") {
$inPrivateParamTypes = 1;
$declaration .= "$curline";
$publicDeclaration = $declaration;
$declaration = "";
} else {
next SWITCH;
}
if (!$stackFrozen) {
if (scalar(@parsedParamList)) {
foreach my $node (@parsedParamList) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@pplStack, $node)
}
}
@parsedParamList = ();
print "parsedParamList pushed\n" if ($parmDebug);
}
@freezeStack = @pplStack;
$stackFrozen = 1;
}
} else {
next SWITCH;
}
}
if (!$seenBraces) { $treeNest = 1;
$treePopTwo = 1;
}
last SWITCH;
}
};
($part =~ /\s/o) && do {
$lastchar = $part;
last SWITCH;
};
($part =~ /\\/o) && do { $lastsymbol = $part; $lastchar = $part; };
($part eq "\"") && do {
print "dquo\n" if ($localDebug);
if (!($inComment || $inInlineComment || $inChar)) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
print "LASTTOKEN: $lasttoken\nCS: $curstring\n" if ($localDebug);
if (($lasttoken !~ /\\$/o) && ($curstring !~ /\\$/o)) {
if (!$inString) {
if (!$seenBraces) { $treeNest = 1;
}
} else {
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [3]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
$inString = (1-$inString);
}
}
$lastchar = $part;
$lastsymbol = "";
last SWITCH;
};
($part eq "[") && do {
print "lbracket\n" if ($localDebug);
if (!($inComment || $inInlineComment || $inString)) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
push(@braceStack, $part); pbs(@braceStack);
if (!$seenBraces) { $treeNest = 1;
}
$curline = spacefix($curline, $part, $lastchar);
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq "]") && do {
print "rbracket\n" if ($localDebug);
if (!($inComment || $inInlineComment || $inString)) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
my $top = pop(@braceStack);
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [4]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($top ne "[") {
warn("$filename:$inputCounter: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);
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq "'") && do {
print "squo\n" if ($localDebug);
if (!($inComment || $inInlineComment || $inString)) {
if ($lastchar ne "\\") {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
if (!$inChar) {
if (!$seenBraces) { $treeNest = 1;
}
} else {
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [5]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
$inChar = !$inChar;
}
if ($lastchar =~ /\=$/o) {
$curline .= " ";
}
}
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq $ilc && ($lang ne "perl" || $lasttoken ne "\$")) && do {
print "ILC\n" if ($localDebug || $ilcDebug);
if (!($inComment || $inChar || $inString || $inRegexp)) {
$inInlineComment = 1;
print "inInlineComment -> 1\n" if ($ilcDebug);
$curline = spacefix($curline, $part, $lastchar, $soc, $eoc, $ilc);
if (!$seenBraces) { $treeNest = 1;
if (!$treePopOnNewLine) {
$treePopOnNewLine = 1;
} else {
$treePopOnNewLine = 0 - $treePopOnNewLine;
}
print "treePopOnNewLine -> $treePopOnNewLine\n" if ($ilcDebug);
}
} elsif ($inComment) {
my $linenum = $inputCounter + $fileoffset;
if (!$argparse) {
warn("$filename:$linenum:Nested comment found [1]. Ignoring.\n");
}
}
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq $soc) && do {
print "SOC\n" if ($localDebug);
if (!($inComment || $inInlineComment || $inChar || $inString)) {
$inComment = 1;
$curline = spacefix($curline, $part, $lastchar);
if (!$seenBraces) {
$treeNest = 1;
}
} elsif ($inComment) {
my $linenum = $inputCounter + $fileoffset;
warn("$filename:$linenum:Nested comment found [2]. Ignoring.\n");
}
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq $eoc) && do {
print "EOC\n" if ($localDebug);
if ($inComment && !($inInlineComment || $inChar || $inString)) {
$inComment = 0;
$curline = spacefix($curline, $part, $lastchar);
$ppSkipOneToken = 1;
if (!$seenBraces) {
$treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [6]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
elsif (!$inComment) {
my $linenum = $inputCounter + $fileoffset;
warn("$filename:$linenum:Unmatched close comment tag found. Ignoring.\n");
} elsif ($inInlineComment) {
my $linenum = $inputCounter + $fileoffset;
warn("$filename:$linenum:Nested comment found [3]. Ignoring.\n");
}
$lastsymbol = "";
$lastchar = $part;
last SWITCH;
};
($part eq "(") && do {
my @tempppl = undef;
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if (!(scalar(@braceStack))) {
print "parsedParamParse -> 2\n" if ($parmDebug);
$parsedParamParse = 2;
print "parsedParamList wiped\n" if ($parmDebug);
@tempppl = @parsedParamList;
@parsedParamList = ();
$parsedParam = "";
}
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
if ($simpleTypedef) {
$simpleTypedef = 0;
$simpleTDcontents = "";
$sodname = $lastsymbol;
$sodclass = "function";
$returntype = "$declaration$curline";
}
$posstypesPending = 0;
if ($callbackNamePending == 2) {
$callbackNamePending = 3;
print "callbackNamePending -> 3\n" if ($localDebug || $cbnDebug);
}
print "lparen\n" if ($localDebug);
push(@braceStack, $part); pbs(@braceStack);
if (!$seenBraces) { $treeNest = 1;
}
$curline = spacefix($curline, $part, $lastchar);
print "LASTCHARCHECK: \"$lastchar\" \"$lastnspart\" \"$curline\".\n" if ($localDebug);
if ($lastnspart eq ")") { print "HERE: DEC IS $declaration\nENDDEC\nCURLINE IS $curline\nENDCURLINE\n" if ($localDebug);
print "SBS: ".scalar(@braceStack)."\n" if ($localDebug);
if (!$callbackNamePending && ($sodclass eq "function") && (scalar(@braceStack) == 1)) { my $temp = pop(@tempppl);
$callbackName = $temp;
$name = "";
$sodclass = "";
$sodname = "";
print "CALLBACKHERE ($temp)!\n" if ($cbnDebug);
}
if ($declaration =~ /.*\n(.*?)\n$/so) {
my $lastline = $1;
print "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 "NEWDEC: $declaration\nNEWCURLINE: $curline\n" if ($localDebug);
} elsif (length($declaration) && $callback_typedef_and_name_on_one_line) {
print "SCARYCASE\n" if ($localDebug);
$declaration =~ s/\n$//so;
$curline = "$declaration $curline";
$declaration = "";
$prespace -= 4;
$prespaceadjust += 4;
$forcenobreak = 1;
}
} else { print "OPARENLC: \"$lastchar\"\nCURLINE IS: \"$curline\"\n" if ($localDebug);}
$lastsymbol = "";
$lastchar = $part;
if ($startOfDec == 2) {
$sodclass = "function";
$freezereturn = 1;
$returntype =~ s/^\s*//so;
$returntype =~ s/\s*$//so;
}
$startOfDec = 0;
if ($curline !~ /\S/o) {
$prespace += 4;
print "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print "PSA: $prespaceadjust\n" if ($localDebug);
}
}
print "OUTGOING CURLINE: \"$curline\"\n" if ($localDebug);
last SWITCH;
};
($part eq ")") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if (scalar(@braceStack) == 1) {
$parsedParamParse = 0;
print "parsedParamParse -> 0\n" if ($parmDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if ($parsedParam ne "void") {
push(@parsedParamList, $parsedParam);
print "pushed $parsedParam into parsedParamList [1]\n" if ($parmDebug);
}
$parsedParam = "";
}
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
print "rparen\n" if ($localDebug);
my $test = pop(@braceStack); pbs(@braceStack);
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [6a]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if (!($test eq "(")) { warn("$filename:$inputCounter:Parentheses do not match.\nWe may have a problem.\n");
warn("Declaration to date: $declaration$curline\n");
}
$curline = spacefix($curline, $part, $lastchar);
$lastsymbol = "";
$lastchar = $part;
$startOfDec = 0;
if ($curline !~ /\S/o) {
$prespace -= 4;
print "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust -= 4;
print "PSA: $prespaceadjust\n" if ($localDebug);
}
}
last SWITCH;
};
($part eq "$lbrace") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
if (scalar(@parsedParamList)) {
foreach my $node (@parsedParamList) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@pplStack, $node)
}
}
@parsedParamList = ();
print "parsedParamList pushed\n" if ($parmDebug);
}
print "parsedParamParse -> 2\n" if ($parmDebug);
$parsedParamParse = 2;
if ($sodclass eq "function" || $inOperator) {
$seenBraces = 1;
if (!$stackFrozen) {
@freezeStack = @pplStack;
$stackFrozen = 1;
}
@pplStack = ();
}
$posstypesPending = 0;
$namePending = 0;
$callbackNamePending = -1;
$simpleTypedef = 0;
$simpleTDcontents = "";
print "callbackNamePending -> -1\n" if ($localDebug || $cbnDebug);
print "lbrace\n" if ($localDebug);
push(@braceStack, $part); pbs(@braceStack);
if (!$seenBraces) { $treeNest = 1;
}
$curline = spacefix($curline, $part, $lastchar);
$lastsymbol = "";
$lastchar = $part;
$startOfDec = 0;
if ($curline !~ /\S/o) {
$prespace += 4;
print "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print "PSA: $prespaceadjust\n" if ($localDebug);
}
}
last SWITCH;
};
($part eq "$rbrace") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
$onlyComments = 0;
if (scalar(@braceStack) == 1) {
$parsedParamParse = 0;
print "parsedParamParse -> 0\n" if ($parmDebug);
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) {
push(@parsedParamList, $parsedParam);
print "pushed $parsedParam into parsedParamList [1b]\n" if ($parmDebug);
}
$parsedParam = "";
} else {
print "parsedParamParse -> 2\n" if ($parmDebug);
$parsedParamParse = 2;
}
if (scalar(@parsedParamList)) {
foreach my $node (@parsedParamList) {
$node =~ s/^\s*//so;
$node =~ s/\s*$//so;
if (length($node)) {
push(@pplStack, $node)
}
}
@parsedParamList = ();
print "parsedParamList pushed\n" if ($parmDebug);
}
print "onlyComments -> 0\n" if ($macroDebug);
print "rbrace\n" if ($localDebug);
my $test = pop(@braceStack); pbs(@braceStack);
if (!$seenBraces) { $treeCur->addSibling($part, 0); $treeSkip = 1;
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [7]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
if (!($test eq "$lbrace") && (!length($structname) || (!($test eq $structname) && $structisbrace))) { warn("$filename:$inputCounter:Braces do not match.\nWe may have a problem.\n");
warn("Declaration to date: $declaration$curline\n");
}
$curline = spacefix($curline, $part, $lastchar);
$lastsymbol = "";
$lastchar = $part;
$startOfDec = 0;
if ($curline !~ /\S/o) {
$prespace -= 4;
print "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust -= 4;
print "PSA: $prespaceadjust\n" if ($localDebug);
}
}
last SWITCH;
};
($part eq $structname || $part =~ /^enum$/o || $part =~ /^union$/o) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if ($structisbrace) {
if ($sodclass eq "function") {
$seenBraces = 1;
if (!$stackFrozen) {
@freezeStack = @pplStack;
$stackFrozen = 1;
}
@pplStack = ();
}
$posstypesPending = 0;
$callbackNamePending = -1;
$simpleTypedef = 0;
$simpleTDcontents = "";
print "callbackNamePending -> -1\n" if ($localDebug || $cbnDebug);
print "lbrace\n" if ($localDebug);
push(@braceStack, $part); pbs(@braceStack);
if (!$seenBraces) { $treeNest = 1;
}
$curline = spacefix($curline, $part, $lastchar);
$lastsymbol = "";
$lastchar = $part;
$startOfDec = 0;
if ($curline !~ /\S/o) {
$prespace += 4;
print "PS: $prespace immediate\n" if ($localDebug);
} else {
$prespaceadjust += 4;
print "PSA: $prespaceadjust\n" if ($localDebug);
}
} else {
if (!$simpleTypedef) {
$simpleTypedef = 2;
}
}
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
$continuation = 1;
if ($basetype eq "") { $basetype = $part; }
if (!($inComment || $inInlineComment || $inString || $inChar)) {
$namePending = 2;
print "namePending -> 2 [2]\n" if ($parseDebug);
if ($posstypesPending) { $posstypes .=" $part"; }
}
if ($sodclass eq "") {
$startOfDec = 0; $sodname = "";
print "sodname cleared (seu)\n" if ($sodDebug);
}
$lastchar = $part;
}; }; ($part =~ /^$typedefname$/) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if (!scalar(@braceStack)) { $callbackIsTypedef = 1; }
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
$continuation = 1;
$simpleTypedef = 1;
if ($part =~ /^$typedefname$/) {
if (!($inComment || $inInlineComment || $inString || $inChar)) {
if ($pascal) {
$namePending = 2;
$inPType = 1;
print "namePending -> 2 [3]\n" if ($parseDebug);
}
if ($posstypesPending) { $posstypes .=" $part"; }
if (!($callbackNamePending)) {
print "callbackNamePending -> 1\n" if ($localDebug || $cbnDebug);
$callbackNamePending = 1;
}
}
}
if ($sodclass eq "") {
$startOfDec = 0; $sodname = "";
print "sodname cleared ($typedefname)\n" if ($sodDebug);
}
$lastchar = $part;
}; };
($part eq "$operator") && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
$inOperator = 1;
$sodname = "";
}
$lastsymbol = $part;
$lastchar = $part;
last SWITCH;
};
($part =~ /;/o) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if ($parsedParamParse) {
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) { push(@parsedParamList, $parsedParam); }
print "pushed $parsedParam into parsedParamList [2semi]\n" if ($parmDebug);
$parsedParam = "";
}
$parsedParamParse = 2;
$freezereturn = 1;
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
print "valuepending -> 0\n" if ($valueDebug);
$valuepending = 0;
$continuation = 1;
if ($occmethod) {
$prespaceadjust = -$prespace;
}
if ($part =~ /;/o && !$inMacroLine && !$inMacro) {
my $bsCount = scalar(@braceStack);
if (!$bsCount && !$kr_c_function) {
if ($startOfDec == 2) {
$sodclass = "constant";
$startOfDec = 1;
} elsif (!($inComment || $inInlineComment || $inChar || $inString)) {
$startOfDec = 1;
}
}
if (!$bsCount) {
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [8]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
while ($treePopTwo--) {
$treeCur = pop(@treeStack) || $treeTop;
print "TSPOP [9]\n" if ($tsDebug || $treeDebug);
bless($treeCur, "HeaderDoc::ParseTree");
}
$treePopTwo = 0;
}
}
$lastchar = $part;
}; }; ($part eq "=" && ($lastsymbol ne "operator")) && do {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
if ($part =~ /=/o && !scalar(@braceStack) &&
$nextpart !~ /=/o && $lastchar !~ /=/o &&
$sodclass ne "function" && !$inPType) {
print "valuepending -> 1\n" if ($valueDebug);
$valuepending = 1;
$preEqualsSymbol = $lastsymbol;
$sodclass = "constant";
$startOfDec = 0;
}; }; ($part =~ /,/o) && do {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
if ($part =~ /,/o && $parsedParamParse && (scalar(@braceStack) == 1)) {
$parsedParam =~ s/^\s*//so; # trim leading space
$parsedParam =~ s/\s*$//so; # trim trailing space
if (length($parsedParam)) { push(@parsedParamList, $parsedParam); }
print "pushed $parsedParam into parsedParamList [2]\n" if ($parmDebug);
$parsedParam = "";
$parsedParamParse = 2;
print "parsedParamParse -> 2\n" if ($parmDebug);
}; }; {
if (!($inString || $inComment || $inInlineComment || $inChar)) {
if (!ignore($part, $ignoreref, $perheaderignoreref)) {
if ($part =~ /\S/o) {
$onlyComments = 0;
print "onlyComments -> 0\n" if ($macroDebug);
}
if (!$continuation && !$occspace) {
$curline = spacefix($curline, $part, $lastchar);
} else {
$continuation = 0;
$occspace = 0;
}
if (length($part) && !($inComment || $inInlineComment)) {
if ($localDebug && $lastchar eq ")") {print "LC: $lastchar\nPART: $part\n";}
if ($lastchar eq ")" && $sodclass eq "function" && ($lang eq "C" || $lang eq "Csource")) {
if ($part !~ /^\s*;/o) {
if (!isKeyword($part, $keywordhashref, $case_sensitive)) {
print "K&R C FUNCTION FOUND [2].\n" if ($localDebug);
$kr_c_function = 1;
$kr_c_name = $sodname;
}
}
}
$lastchar = $part;
if ($part =~ /\w/o || $part eq "::") {
if ($callbackNamePending == 1) {
if (!($part =~ /^struct$/o || $part =~ /^enum$/o || $part =~ /^union$/o || $part =~ /^$typedefname$/)) {
print "callbackNamePending -> 2\n" if ($localDebug || $cbnDebug);
$callbackNamePending = 2;
}
} elsif ($callbackNamePending == 3) {
print "callbackNamePending -> 4\n" if ($localDebug || $cbnDebug);
$callbackNamePending = 4;
$callbackName = $part;
$name = "";
$sodclass = "";
$sodname = "";
} elsif ($callbackNamePending == 4) {
if ($part eq "::") {
print "callbackNamePending -> 5\n" if ($localDebug || $cbnDebug);
$callbackNamePending = 5;
$callbackName .= $part;
} elsif ($part !~ /\s/o) {
print "callbackNamePending -> 0\n" if ($localDebug || $cbnDebug);
$callbackNamePending = 0;
}
} elsif ($callbackNamePending == 5) {
if ($part !~ /\s/o) {
print "callbackNamePending -> 4\n" if ($localDebug || $cbnDebug);
if ($part !~ /\*/o) {
$callbackNamePending = 4;
}
$callbackName .= $part;
}
}
if ($namePending == 2) {
$namePending = 1;
print "namePending -> 1 [4]\n" if ($parseDebug);
} elsif ($namePending) {
if ($name eq "") { $name = $part; }
$namePending = 0;
print "namePending -> 0 [5]\n" if ($parseDebug);
}
} if ($part !~ /[;\[\]]/o && !$inBrackets) {
my $opttilde = "";
if ($seenTilde) { $opttilde = "~"; }
if ($startOfDec == 1) {
print "Setting sodname (maybe type) to \"$part\"\n" if ($sodDebug);
$sodname = $opttilde.$part;
if ($part =~ /\w/o) {
$startOfDec++;
}
} elsif ($startOfDec == 2) {
if ($part =~ /\w/o && !$inTemplate) {
$preTemplateSymbol = "";
}
if ($inOperator) {
$sodname .= $part;
} else {
if (length($sodname)) {
$sodtype .= " $sodname";
}
$sodname = $opttilde.$part;
}
print "sodname set to $part\n" if ($sodDebug);
} else {
$startOfDec = 0;
}
} elsif ($part eq "[") { $inBrackets += 1;
print "inBrackets -> $inBrackets\n" if ($sodDebug);
} elsif ($part eq "]") {
$inBrackets -= 1;
print "inBrackets -> $inBrackets\n" if ($sodDebug);
} if (!($part eq $eoc)) {
if ($typestring eq "") { $typestring = $part; }
if ($lastsymbol =~ /\,\s*$/o) {
$lastsymbol .= $part;
} elsif ($part =~ /^\s*\;\s*$/o) {
$lastsymbol .= $part;
} elsif (length($part)) {
$lastsymbol = $part;
}
} } }
} } } if (length($part)) { $lasttoken = $part; }
if (length($part) && $inRegexpTrailer) { --$inRegexpTrailer; }
if ($postPossNL) { --$postPossNL; }
if (($simpleTypedef == 1) && ($part ne $typedefname) &&
!($inString || $inComment || $inInlineComment || $inChar ||
$inRegexp)) {
$simpleTDcontents .= $part;
}
my $ignoretoken = ignore($part, $ignoreref, $perheaderignoreref);
my $hide = ($ignoretoken && !($inString || $inComment || $inInlineComment || $inChar));
print "TN: $treeNest TS: $treeSkip\n" if ($tsDebug);
if (!$treeSkip) {
if (!$seenBraces) { if ($treeNest != 2) {
if (length($treepart)) {
$treeCur = $treeCur->addSibling($treepart, $hide);
$treepart = "";
} else {
$treeCur = $treeCur->addSibling($part, $hide);
}
bless($treeCur, "HeaderDoc::ParseTree");
}
if ($treeNest) {
print "TSPUSH\n" if ($tsDebug || $treeDebug);
push(@treeStack, $treeCur);
$treeCur = $treeCur->addChild("", 0);
bless($treeCur, "HeaderDoc::ParseTree");
}
}
}
$treeNest = 0;
if (!$freezereturn) {
$returntype = "$declaration$curline";
}
if (($inString || $inComment || $inInlineComment || $inChar) ||
!$ignoretoken) {
if (!($inString || $inComment || $inInlineComment || $inChar) &&
!$ppSkipOneToken) {
if ($parsedParamParse == 1) {
$parsedParam .= $part;
} elsif ($parsedParamParse == 2) {
$parsedParamParse = 1;
print "parsedParamParse -> 1\n" if ($parmDebug);
}
}
$ppSkipOneToken = 0;
print "MIDPOINT CL: $curline\nDEC:$declaration\nSCR: \"$scratch\"\n" if ($localDebug);
if (!$seenBraces) {
if ($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 "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 "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 &&
!$occmethod) ||
($part =~ /[:;.]/o && $nextpart !~ /\n/o &&
$occmethod)) {
if ($curline !~ /\n/o && !($inMacro || ($pascal && scalar(@braceStack)) || $inInlineComment || $inComment || $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 "ZEROSCRATCH\n";
print "zDec: \"$zDec\"\n";
}
}
$declaration .= "$scratch$curline";
print "CURLINE CLEAR [3]\n" if ($localDebug);
$curline = "";
print "PS: $prespace -> " . $prespace + $prespaceadjust . "\n" if ($localDebug);
$prespace += $prespaceadjust;
$prespaceadjust = 0;
} elsif ($part =~ /[\(;,]/o && $nextpart !~ /\n/o &&
($occmethod == 1)) {
print "SPC\n" if ($localDebug);
$curline .= " "; $occspace = 1;
} else {
print "NOSPC: $part:$nextpart:$occmethod\n" if ($localDebug);
}
}
}
print "CURLINE IS \"$curline\".\n" if ($localDebug);
my $bsCount = scalar(@braceStack);
print "ENDTEST: $bsCount \"$lastsymbol\"\n" if ($localDebug);
print "KRC: $kr_c_function SB: $seenBraces\n" if ($localDebug);
if (!$bsCount && $lastsymbol =~ /;\s*$/o) {
if (!$kr_c_function || $seenBraces) {
$continue = 0;
print "continue -> 0 [3]\n" if ($localDebug);
}
} else {
print("bsCount: $bsCount, ls: $lastsymbol\n") if ($localDebug);
pbs(@braceStack);
}
if (!$bsCount && $seenBraces && ($sodclass eq "function" || $inOperator) &&
($nextpart ne ";")) {
$continue = 0;
print "continue -> 0 [4]\n" if ($localDebug);
}
if (($inMacro == 3 && $lastsymbol ne "\\") || $inMacro == 4) {
if ($part =~ /[\n\r]/o) {
print "MLS: $lastsymbol\n" if ($macroDebug);
$continue = 0;
print "continue -> 0 [5]\n" if ($localDebug);
}
} elsif ($inMacro == 2) {
warn "$filename:$inputCounter:Declaration starts with # but is not preprocessor macro\n";
} elsif ($inMacro == 3 && $lastsymbol eq "\\") {
print "TAIL BACKSLASH ($continue)\n" if ($localDebug || $macroDebug);
}
if ($valuepending == 2) {
$value .= $part;
} elsif ($valuepending) {
$valuepending = 2;
print "valuepending -> 2\n" if ($valueDebug);
}
}
if (length($part) && $part =~ /\S/o) { $lastnspart = $part; }
if ($seenTilde && length($part) && $part !~ /\s/o) { $seenTilde--; }
$part = $nextpart;
} }
if ($curline !~ /\n/) { $curline =~ s/^\s*//go; }
if ($curline =~ /\S/o) {
$scratch = nspaces($prespace);
$declaration .= "$scratch$curline\n";
}
print "($typestring, $basetype)\n" if ($localDebug || $listDebug);
print "LS: $lastsymbol\n" if ($localDebug);
my $typelist = "";
my $namelist = "";
my @names = split(/[,\s;]/, $lastsymbol);
foreach my $insname (@names) {
$insname =~ s/\s//so;
$insname =~ s/^\*//sgo;
if (length($insname)) {
$typelist .= " $typestring";
$namelist .= ",$insname";
}
}
$typelist =~ s/^ //o;
$namelist =~ s/^,//o;
if ($pascal) {
if (!length($typelist)) {
$typelist .= "$typestring";
$namelist .= "$name";
}
}
print "TL (PRE): $typelist\n" if ($localDebug);
if (!length($basetype)) { $basetype = $typestring; }
print "BT: $basetype\n" if ($localDebug);
print "NAME is $name\n" if ($localDebug || $listDebug);
if ($name && length($name) && !$simpleTypedef && (!($HeaderDoc::outerNamesOnly || $argparse == 2) || !length($namelist))) {
my $quotename = quote($name);
if ($namelist !~ /$quotename/) {
if (length($namelist)) {
$namelist .= ",";
$typelist .= " ";
}
$namelist .= "$name";
$typelist .= "$basetype";
}
} else {
if (!scalar(@names)) {
print "Empty output ($basetype, $typestring).\n" if ($localDebug || $listDebug);
$namelist = " ";
$typelist = "$basetype";
}
print "NUMNAMES: ".scalar(@names)."\n" if ($localDebug || $listDebug);
}
print "NL: \"$namelist\".\n" if ($localDebug || $listDebug);
print "TL: \"$typelist\".\n" if ($localDebug || $listDebug);
print "PT: \"$posstypes\"\n" if ($localDebug || $listDebug);
$callbackName =~ s/^.*:://o;
$callbackName =~ s/^\*+//o;
print "CBN: \"$callbackName\"\n" if ($localDebug || $listDebug);
if (length($callbackName)) {
$name = $callbackName;
print "DEC: \"$declaration\"\n" if ($localDebug || $listDebug);
$namelist = $name;
if ($callbackIsTypedef) {
$typelist = "typedef";
$posstypes = "function";
} else {
$typelist = "function";
$posstypes = "typedef";
}
print "NL: \"$namelist\".\n" if ($localDebug || $listDebug);
print "TL: \"$typelist\".\n" if ($localDebug || $listDebug);
print "PT: \"$posstypes\"\n" if ($localDebug || $listDebug);
}
if (length($preTemplateSymbol) && ($sodclass eq "function")) {
$sodname = $preTemplateSymbol;
$sodclass = "ftmplt";
$posstypes = "ftmplt function method"; }
print "TVALUE: $value\n" if ($localDebug);
if ($sodclass ne "constant") {
$value = "";
} elsif (length($value)) {
$value =~ s/^\s*//so;
$value =~ s/\s*$//so;
$posstypes = "constant";
$sodname = $preEqualsSymbol;
}
if (length($kr_c_name)) { $sodname = $kr_c_name; $sodclass = "function"; }
if (length($sodname) && !$occmethod) {
if (!length($callbackName)) { if (!$perl_or_shell) {
$name = $sodname;
$namelist = $name;
}
$typelist = "$sodclass";
if (!length($preTemplateSymbol)) {
$posstypes = "$sodclass";
}
print "SETTING NAME/TYPE TO $sodname, $sodclass\n" if ($sodDebug);
if ($sodclass eq "function") {
$posstypes .= " method";
}
}
}
print "DEC: $declaration\n" if ($sodDebug || $localDebug);
if ($occmethod) {
$typelist = "method";
$posstypes = "method function";
if ($occmethod == 2) {
$namelist = "$occmethodname";
}
}
if ($inMacro == 3) {
$typelist = "#define";
$posstypes = "function method";
$namelist = $sodname;
$value = "";
@parsedParamList = ();
if ($declaration =~ / my $pplref = defParmParse($declaration, $inputCounter);
print "parsedParamList replaced\n" if ($parmDebug);
@parsedParamList = @{$pplref};
} else {
$posstypes = "constant";
}
} elsif ($inMacro == 4) {
$typelist = "MACRO";
$posstypes = "MACRO";
$value = "";
@parsedParamList = ();
}
if ($inOperator) {
$typelist = "operator";
$posstypes = "function";
}
my $privateDeclaration = "";
if ($inPrivateParamTypes) {
$privateDeclaration = $declaration;
$declaration = $publicDeclaration;
}
print "TYPELIST WAS \"$typelist\"\n" if ($localDebug);;
print "LEFTBP\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 ($stackFrozen) { @pplStack = @freezeStack; }
if ($localDebug) {
foreach my $stackitem (@pplStack) {
print "stack contained $stackitem\n";
}
}
$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)) {
print "SIMPLETYPEDEF: $inputCounter, $declaration, $typelist, $namelist, $posstypes, $value, OMITTED pplStack, $returntype, $privateDeclaration, $treeTop, $simpleTDcontents, $availability\n" if ($parseDebug || $sodDebug || $localDebug);
$typelist = "typedef";
$namelist = $sodname;
$posstypes = "";
}
if (length($sodtype) && !$occmethod) {
$returntype = $sodtype;
}
return ($inputCounter, $declaration, $typelist, $namelist, $posstypes, $value, \@pplStack, $returntype, $privateDeclaration, $treeTop, $simpleTDcontents, $availability);
}
sub spacefix
{
my $curline = shift;
my $part = shift;
my $lastchar = shift;
my $soc = shift;
my $eoc = shift;
my $ilc = shift;
my $localDebug = 0;
if ($HeaderDoc::use_styles) { return $curline; }
print "SF: \"$curline\" \"$part\" \"$lastchar\"\n" if ($localDebug);
if (($part !~ /[;,]/o)
&& length($curline)) {
if ($part eq $ilc) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part eq $soc) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part eq $eoc) {
if ($lastchar ne " ") {
$curline .= " ";
}
}
elsif ($part =~ /\(/o) {
print "PAREN\n" if ($localDebug);
if ($curline !~ /[\)\w\*]\s*$/o) {
print "CASEA\n" if ($localDebug);
if ($lastchar ne " ") {
print "CASEB\n" if ($localDebug);
$curline .= " ";
}
} else {
print "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 "BS: ";
foreach my $p (@braceStack) { print "$p "; }
print "ENDBS\n";
}
}
sub defParmParse
{
my $declaration = shift;
my $inputCounter = shift;
my @myargs = ();
my $localDebug = 0;
my $curname = "";
my $filename = "";
$declaration =~ s/.* my @braceStack = ( "(" );
my @tokens = split(/(\W)/, $declaration);
foreach my $token (@tokens) {
print "TOKEN: $token\n" if ($localDebug);
if (!scalar(@braceStack)) { last; }
if ($token =~ /[\(\[]/o) {
print "open paren/bracket - $token\n" if ($localDebug);
push(@braceStack, $token);
} elsif ($token =~ /\)/o) {
print "close paren\n" if ($localDebug);
my $top = pop(@braceStack);
if ($top !~ /\(/o) {
warn("$filename:$inputCounter:Parentheses do not match (macro).\nWe may have a problem.\n");
}
} elsif ($token =~ /\]/o) {
print "close bracket\n" if ($localDebug);
my $top = pop(@braceStack);
if ($top !~ /\[/o) {
warn("$filename:$inputCounter: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 "pushed \"$curname\"\n" if ($localDebug);
$curname = "";
} else {
$curname .= $token;
}
}
$curname =~ s/^\s*//sgo;
$curname =~ s/\s*$//sgo;
if (length($curname)) {
print "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;
my $def = $HeaderDoc::availability_defs{$part};
if ($def && length($def)) { return $def; }
if ($ignorelist{$part}) {
print "IGNORING $part\n" if ($localDebug);
return 1;
}
if ($perheaderignorelist{$part}) {
print "IGNORING $part\n" if ($localDebug);
return 1;
}
print "NO MATCH FOUND\n" if ($localDebug);
return 0;
}
1;