* @version $Id: Parser.inc 238276 2007-06-22 14:58:30Z ashnazg $
* @package phpDocumentor
* @subpackage Parsers
* @deprecated in favor of {@link phpDocumentorTParser}
*/
class Parser extends Publisher
{
/**#@+
* @access private
*/
/**
* Word parser
* @see WordParser
*/
var $wp;
/**
* temporary parser variables
*/
var $p_vars = array('func' => false, 'function_data' => '', 'quote_data' => '', 'event_stack' => false, 'last_pevent' => 0,
'two_words_ago' => '', 'temp_word' => '', 'docblock' => false, 'line' => array(), 'linecount' => 0, 'startword' => '',
'periodline' => 0, 'shortdesc' => '', 'docblock_desc' => '', 'class' => false, 'source_location' => '',
'define_params_data' => '', 'define' => false, 'define_name' => '', 'define_value' => '', 'var' => false,
'oldtoken' => false, 'comment_data' => '', 'function_param' => NULL, 'inline_dockeyword_type' => false,
'inline_dockeyword_data' => false, 'dockeyword_type' => false, 'dockeyword_data' =>false, 'param_var' => false,
'include_name' => '', 'include_value' => '','include' => false, 'return_type' => '', 'cur_class' => '', 'property_name' => false,
'function_data' => false, 'varname' => '', 'returntype' => false, 'vartype' => false, 'paramtype' => false,
'tagname' => '', 'find_global' => '', 'global_type' => '', 'paramname' => false, 'statics' => array(),
'static_count' => 0, 'static_val' => array(), 'docblock_type' => 'docblock', 'seelement' => false);
/**
* parser flags, for states that don't warrant a new event (like new line in a docblock)
*/
var $p_flags = array('docblocknewline' => false, 'docblockintags' => false, 'useperiod' => false,
'definename_isset' => false, 'define_parens' => false, 'reset_quote_data' => false,
'in_desc' => true, 'in_tag' => false, 'newline' => true, 'tempnewline' => false,
'start_docblock' => false, 'includename_isset' => false, 'return_isset' => false,
'is_return' => false, 'in_class' => false, 'asterisk' => false, 'var_equals' => false,
'arrayinvarname' => false, 'valid_newline' => true, 'startline' => false,
'function_global' => false, 'define_global' => false, 'static_value' => false,'funcparam_val' => false,
'get_source' => false, 'getting_source' => false);
/**
* lookup table for event handler methods
* @see Parser::parse()
*/
var $eventHandlers = array(
'handleArray' => PARSER_EVENT_ARRAY,
'handleClass' => PARSER_EVENT_CLASS,
'handleComment' => PARSER_EVENT_COMMENT,
'handleDocBlockTemplate' => PARSER_EVENT_DOCBLOCK_TEMPLATE,
'handleEndDocBlockTemplate' => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
'handleEscape' => PARSER_EVENT_ESCAPE,
'handleLogicBlock' => PARSER_EVENT_LOGICBLOCK,
'defaultHandler' => PARSER_EVENT_NOEVENTS,
// 'defaultHandler' => PARSER_EVENT_COMMENTBLOCK, (set in constructor below)
// 'defaultHandler' => PARSER_EVENT_OUTPHP,
'handleDefine' => PARSER_EVENT_DEFINE,
'handleDefineParams' => PARSER_EVENT_DEFINE_PARAMS,
'handleDefineParamsParenthesis' => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
'handleIncludeParamsParenthesis' => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
// 'handleDocBlock' => PARSER_EVENT_DOCBLOCK,
'BetterhandleDocBlock' => PARSER_EVENT_DOCBLOCK,
'handleTags' => PARSER_EVENT_TAGS,
'handleDesc' => PARSER_EVENT_DESC,
// 'handleDockeyword' => PARSER_EVENT_DOCKEYWORD,
'handleTag' => PARSER_EVENT_DOCKEYWORD,
'handleDockeywordEmail' => PARSER_EVENT_DOCKEYWORD_EMAIL,
'handleEOFQuote' => PARSER_EVENT_EOFQUOTE,
'handleFunction' => PARSER_EVENT_FUNCTION,
'handleFunctionParams' => PARSER_EVENT_FUNCTION_PARAMS,
'handleFuncGlobal' => PARSER_EVENT_FUNC_GLOBAL,
'handleGlobal' => PARSER_EVENT_DEFINE_GLOBAL,
'handleGlobalValue' => PARSER_EVENT_GLOBAL_VALUE,
'handleInlineDockeyword' => PARSER_EVENT_INLINE_DOCKEYWORD,
'handleInclude' => PARSER_EVENT_INCLUDE,
'handleIncludeParams' => PARSER_EVENT_INCLUDE_PARAMS,
'handleQuote' => PARSER_EVENT_QUOTE,
'handlePhpCode' => PARSER_EVENT_PHPCODE,
'handleSingleQuote' => PARSER_EVENT_SINGLEQUOTE,
'handleStaticVar' => PARSER_EVENT_STATIC_VAR,
'handleStaticValue' => PARSER_EVENT_STATIC_VAR_VALUE,
'handleVar' => PARSER_EVENT_VAR,
);
/**
* event handlers for @tags
* @tutorial tags.pkg
*/
var $tagHandlers = array(
'*' => 'defaultTagHandler',
'category' => 'categoryTagHandler',
'example' => 'exampleTagHandler',
'filesource' => 'invalidTagHandler',
'return' => 'returnTagHandler',
'returns' => 'returnTagHandler',
'var' => 'varTagHandler',
'package' => 'packageTagHandler',
'param' => 'paramTagHandler',
'parameter' => 'paramTagHandler',
'global' => 'globalTagHandler',
'staticvar' => 'staticvarTagHandler',
'uses' => 'usesTagHandler',
'property' => 'propertyTagHandler',
'property-read' => 'propertyTagHandler',
'property-write' => 'propertyTagHandler',
'method' => 'propertyTagHandler'
);
var $laststart = false;
/**
* An array of allowable @tags
*/
var $allowableTags;
/**
* An array of allowed inline @tags
*/
var $allowableInlineTags;
/**
* Sets the states up, and creates a new WordParser
*/
/**
* an array of parsing tokens organized by event number.
* A token is defined as the smallest group of characters that separates or
* defines a new parser element. In English, a space or punctuation are
* tokens that separate words. in PHP, tokens may be //, or even "
* Format: array(eventnum =>array(token1, token2, token3, ...),...)
* @var array
*/
var $tokens;
/**
* array of events that are raised, organized by the tokens that raise them.
* Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)
* @var array
*/
var $pushEvent;
/**
* array of tokens that end an event, organized by event
* Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)
* @var array
*/
var $popEvent;
/**#@-*/
/**
* Set up invariant parsing variables
*/
function Parser()
{
$this->allowableTags = $GLOBALS['_phpDocumentor_tags_allowed'];
$this->allowableInlineTags = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
$this->wp = new WordParser;
// strange PHP 4.0.6 behavior: it converts constants to strings without warning if it's an array index
$this->eventHandlers = array_flip($this->eventHandlers);
$this->eventHandlers[PARSER_EVENT_COMMENTBLOCK] = 'defaultHandler';
$this->eventHandlers[PARSER_EVENT_OUTPHP] = 'defaultHandler';
$this->subscribe(PHPDOCUMENTOR_EVENT_NEWLINENUM,$GLOBALS['phpDocumentor_errors']);
$this->subscribe(PHPDOCUMENTOR_EVENT_NEWFILE,$GLOBALS['phpDocumentor_errors']);
}
/**
* Parse a new file
*
* @param string $parse_data
* @param string $path
* @param int $base number of directories to drop off the bottom when creating names using path
* @staticvar integer used for recursion limiting if a handler for an event is not found
* @return bool
*/
function parse (&$parse_data, $path, $base = 0, $packages = false)
{
global $_phpDocumentor_options;
static $endrecur = 0;
$this->p_vars = array('func' => false, 'function_data' => '', 'quote_data' => '', 'event_stack' => false, 'last_pevent' => 0,
'two_words_ago' => '', 'temp_word' => '', 'docblock' => false, 'line' => array(), 'linecount' => 0, 'startword' => '',
'periodline' => 0, 'shortdesc' => '', 'docblock_desc' => '', 'class' => false, 'source_location' => '',
'define_params_data' => '', 'define' => false, 'define_name' => '', 'define_value' => '', 'var' => false,
'oldtoken' => false, 'comment_data' => '', 'function_param' => NULL, 'inline_dockeyword_type' => false,
'inline_dockeyword_data' => false, 'dockeyword_type' => false, 'dockeyword_data' =>false, 'param_var' => false,
'include_name' => '', 'include_value' => '','include' => false, 'return_type' => '', 'cur_class' => '', 'property_name' => false,
'function_data' => false, 'varname' => '', 'returntype' => false, 'vartype' => false, 'paramtype' => false,
'tagname' => '', 'find_global' => '', 'global_type' => '', 'paramname' => false, 'statics' => array(),
'static_count' => 0, 'static_val' => array(), 'docblock_type' => 'docblock', 'linenum' => false,
'seelement' => false);
$this->p_flags = array('docblocknewline' => false, 'docblockintags' => false, 'useperiod' => false,
'definename_isset' => false, 'define_parens' => false, 'reset_quote_data' => false,
'in_desc' => true, 'in_tag' => false, 'newline' => true, 'tempnewline' => false,
'start_docblock' => false, 'includename_isset' => false, 'return_isset' => false,
'is_return' => false, 'in_class' => false, 'asterisk' => false, 'var_equals' => false,
'arrayinvarname' => false, 'valid_newline' => true, 'startline' => false,
'function_global' => false, 'define_global' => false, 'static_value' => false,'funcparam_val' => false,
'get_source' => false, 'getting_source' => false, 'in_define' => false, 'in_include' => false,
'in_var' => false, 'in_global' => false);
$this->p_vars['parsepath'] = $path;
$this->setupStates();
if (strlen($parse_data) == 0)
{
return false;
}
// initialize variables so E_ALL error_reporting doesn't complain
$pevent = 0;
$word = 0;
$this->p_vars['event_stack'] = new EventStack;
$this->wp->setup($parse_data);
$page = new ParserPage;
$page->setPath($path);
$page->setPackageOutput($packages);
$page->setFile(basename($path));
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWFILE,basename($path));
//$name = str_replace("/","_",dirname($path)) . "_" . array_shift(explode(".",$page->getFile()));
// fc@fc.clever-soft.com 11/29/2001
$name = str_replace( ':', '', dirname($path) . PATH_DELIMITER . $page->getFile() );
$tmp = explode( PATH_DELIMITER, $name );
$name = implode( "---", array_slice( $tmp, $base ) );
// if base is '', drive letter is present in windows
$page->setName($name);
$temploc = $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER. implode(PATH_DELIMITER,
array_slice(explode(PATH_DELIMITER,$path),$base));
if ($temploc == $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER) $temploc .= $path;
$this->p_vars['source_location'] = $source_location = $temploc;
$page->setSourceLocation($source_location);
$this->publishEvent(PHPDOCUMENTOR_EVENT_PAGE,$page);
unset($page);
$this->p_flags['reset_quote_data'] = true;
do
{
$lpevent = $pevent;
$pevent = $this->p_vars['event_stack']->getEvent();
if ($lpevent != $pevent)
{
$this->p_vars['last_pevent'] = $lpevent;
}
if ($this->p_vars['last_pevent'] != $pevent)
{
// its a new event so the word parser needs to be reconfigured
$this->configWordParser($pevent);
}
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent + 100));
if ($pevent == PARSER_EVENT_GLOBAL_VALUE || $pevent == PARSER_EVENT_DOCBLOCK || $pevent == PARSER_EVENT_DOCBLOCK_TEMPLATE)
{
$this->wp->setWhitespace(true);
}
$this->p_vars['last_word'] = $word;
$word = $this->wp->getWord();
// in wordparser, have to keep track of lines
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM, $this->wp->linenum);
if (PHPDOCUMENTOR_DEBUG == true)
{
echo "\nLAST: |" . $this->p_vars['last_word'] . "|\n";
echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
echo "LASTPEVENT: " . $this->getParserEventName($this->p_vars['last_pevent']) . "\n";
echo $this->wp->getPos() . ": |$word|\n--------------------------\n\n";
}
if ($this->p_flags['get_source'])
{
if ($pevent == PARSER_EVENT_FUNCTION)
{
$this->wp->retrievesource("function $word");
$this->p_flags['get_source'] = false;
$this->p_flags['getting_source'] = true;
}
}
if (false)//$this->p_flags['getting_source'] && ($pevent == PARSER_EVENT_DOCBLOCK) || ($pevent == PARSER_EVENT_NOEVENTS))
{
addError(PDERROR_SOURCE_TAG_FUNCTION_NOT_FOUND);
// throw away source
$this->wp->getSource();
}
if (isset($this->eventHandlers[$pevent]))
{
$handle = $this->eventHandlers[$pevent];
$this->$handle($word, $pevent);
} else
{
debug('WARNING: possible error, no handler for event number '.$pevent);
if ($endrecur++ == 25)
{
die("FATAL ERROR, recursion limit reached");
}
}
} while (!($word === false));
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_PAGE);
}
/**#@+
* @access private
* @param string token parsed from source
* @param integer parser constant from {@link Parser.inc}
*/
/**
* handler for NOEVENTS, OUTPHP, COMMENTBLOCK
*/
function defaultHandler($word, $pevent)
{
$this->checkEventPush( $word, $pevent);
$this->checkEventPop($word,$pevent);
}
/**
* handler for LOGICBLOCK
*
* Logic Blocks are the stuff between { and } in a function/method. A
* logic block can clearly contain other logic blocks, as in:
*
*
* function test($a)
* {
* if (testcondition)
* { // nested logic block
* }
* }
*
*
* So, the exit portion of the logic block handler must check to see if the
* logic block being exited is the top-level, and it does this by retrieving
* the last event from the stack. If it is a function (and not a logic block)
* then it backs up the word parser so that the function will exit properly.
*
* {@source 11}
*/
function handleLogicBlock($word, $pevent)
{
$a = $this->checkEventPush( $word, $pevent);
if ($a == PARSER_EVENT_FUNC_GLOBAL || $a == PARSER_EVENT_STATIC_VAR)
{
if (substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != ' ' && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "\t" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "\n" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != ";" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "}" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "{")
{
$this->p_vars['event_stack']->popEvent();
}
}
if ($this->checkEventPop($word,$pevent))
{
$e = $this->p_vars['event_stack']->popEvent();
$this->p_vars['event_stack']->pushEvent($e);
if ($e == PARSER_EVENT_FUNCTION)
{
$this->wp->backupPos($word);
}
}
}
/**
* handler for ESCAPE.
* this event handler parses "this string \"with its escape backslashes\""
and returns:
* this string "with its escape backslashes"
* to make it human-readable
*/
function handleEscape($word, $pevent)
{
$this->p_vars['event_stack']->popEvent();
}
/**
* handler for COMMENT.
* this event handler parses single-line comments like:
* // this one
*/
function handleComment($word, $pevent)
{
$this->checkEventPush( $word, $pevent);
if (!isset($this->p_vars['comment_data'])) $this->p_vars['comment_data'] = '';
$this->p_vars['comment_data'] .= $word;
$this->checkEventPop($word,$pevent);
}
/**
* handler for ARRAY.
* this event handler parses arrays in default values of function and var definitions
*/
function handleArray($word, $pevent)
{
$e = $this->checkEventPush( $word, $pevent);
if (($e == PARSER_EVENT_COMMENTBLOCK) ||
($e == PARSER_EVENT_COMMENT)) return;
if (!isset($this->p_vars['function_data']) || (isset($this->p_vars['function_data']) && empty($this->p_vars['function_data'])))
{
$this->p_vars['function_data'] = "array";
}
if ( ($this->p_vars['last_word'] == "'"))
{
$this->p_vars['function_data'] .= $this->p_vars['quote_data']."'";
}
if ( ($this->p_vars['last_word'] == "\""))
{
$this->p_vars['function_data'] .= $this->p_vars['quote_data']."\"";
}
$this->p_vars['function_data'] .= $word;
//echo "function_data = |$this->p_vars['function_data']|\n";
if ($this->checkEventPop($word,$pevent))
{
}
}
/**
* handler for DEFINE.
* handles define(constant, value); statements
*/
function handleDefine($word, $pevent)
{
if (!$this->p_flags['in_define'])
{
$this->p_vars['linenum'] = $this->wp->linenum;
}
$this->p_flags['in_define'] = true;
$this->checkEventPush( $word, $pevent);
$this->p_flags['definename_isset'] = false;
$this->p_vars['define_params_data'] = '';
unset($this->p_vars['quote_data']);
if ($this->checkEventPop($word,$pevent))
{
$this->p_flags['in_define'] = false;
$this->p_vars['define'] = new parserDefine;
$this->p_vars['define']->setLineNumber($this->p_vars['linenum']);
$this->p_vars['define']->setName($this->p_vars['define_name']);
$this->p_vars['define']->setValue($this->p_vars['define_value']);
$this->publishEvent(PHPDOCUMENTOR_EVENT_DEFINE,$this->p_vars['define']);
$this->p_flags['definename_isset'] = false;
unset($this->p_vars['define']);
unset($this->p_vars['define_name']);
unset($this->p_vars['define_value']);
$this->p_flags['in_define'] = false;
$this->p_vars['define_params_data'] = '';
}
}
/**
* handler for DEFINE_PARAMS.
* handles the parsing of constant and value in define(constant, value);
*/
function handleDefineParams($word, $pevent)
{
if ($this->checkEventPush( $word, $pevent))
{
if ($word == '(')
{
$this->p_vars['define_params_data'] .= $word;
}
return;
}
$this->p_flags['define_parens'] = true;
if(!isset($this->p_vars['define_params_data'])) $this->p_vars['define_params_data'] = '';
if ($this->checkEventPop($word,$pevent))
{
if (!empty($this->p_vars['quote_data']))
{
$this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];
}
if (!empty($this->p_vars['define_params_data']))
{
//echo $this->p_vars['define_params_data']."\n";
$this->p_vars['define_value'] = $this->p_vars['define_params_data'];
}
else
{
if ( $this->p_vars['last_word'] != "/*" &&
$this->p_vars['last_word'] != "//" && $this->p_vars['last_word'] != "#")
{
$this->p_vars['define_value'] = trim($this->p_vars['last_word']);
}
else
{
$this->p_vars['define_value'] = "";
}
}
}
if ($this->p_flags['definename_isset'])
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['define_params_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
$this->p_vars['define_params_data'] .= $word;
} else
{
if ($word != ",")
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];
unset($this->p_vars['quote_data']);
}
$this->p_vars['define_params_data'] .= $word;
} else
{
if (isset($this->p_vars['quote_data']) && !$this->p_flags['definename_isset'])
{
$this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];
unset($this->p_vars['quote_data']);
}
$this->p_flags['definename_isset'] = true;
$this->p_vars['define_name'] = $this->p_vars['define_params_data'];
unset($this->p_vars['quote_data']);
$this->p_vars['define_params_data'] = '';
}
}
}
/**
* handler for DEFINE_PARAMS_PARENTHESIS.
* this handler takes all parenthetical statements within constant or value in:
* define(constant, value) of a define statement, and handles them properly
*/
function handleDefineParamsParenthesis($word, $pevent)
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['define_params_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
$this->p_vars['define_params_data'] .= $word;
$this->checkEventPush( $word, $pevent);
$this->checkEventPop( $word, $pevent);
}
/**
* handler for CLASS.
* this handler parses a class statement
*/
function handleClass($word, $pevent)
{
$this->p_flags['in_class'] = true;
$a = $this->checkEventPush( $word, $pevent);
if ($a == PARSER_EVENT_DOCBLOCK || $a == PARSER_EVENT_DOCBLOCK_TEMPLATE)
{
$this->wp->setWhitespace(true);
}
if (!isset($this->p_vars['class'])) $this->p_vars['class'] = false;
if (!is_subclass_of($this->p_vars['class'],"parserBase"))
{
$this->p_vars['class'] = new parserClass;
$this->p_vars['class']->setLineNumber($this->wp->linenum);
$this->p_vars['class']->setname($word);
$this->p_vars['cur_class'] = $word;
$this->p_vars['class']->setSourceLocation($this->p_vars['source_location']);
}
if (strtolower($this->p_vars['last_word']) == "extends")
{
$this->p_vars['class']->setExtends($word);
}
if ($word == "{")
{
$this->publishEvent(PHPDOCUMENTOR_EVENT_CLASS,$this->p_vars['class']);
}
//echo $this->wp->getPos() . ": |$word|\n";
if ($this->checkEventPop($word,$pevent))
{
$this->p_flags['in_class'] = false;
// throw an event when class is done
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,STATE_END_CLASS);
$this->p_vars['class'] = false;
}
}
/**
* handler for VAR.
* handle a var $varname = default_value; or var $varname; statement in a class definition
*/
function handleVar($word, $pevent)
{
if (!$this->p_flags['in_var'])
{
$this->p_vars['linenum'] = $this->wp->linenum;
}
$this->p_flags['in_var'] = true;
//echo $word."\n";
$e = $this->checkEventPush( $word, $pevent);
if (!isset($this->p_vars['var'])) $this->p_vars['var'] = false;
if ($word == '=' || $word == ';') $this->p_flags['var_equals'] = true;
if (!$this->p_flags['var_equals'])
{
// if we haven't parsed the = yet, no arrays are possible!
if ($e == PARSER_EVENT_ARRAY)
{
$this->p_flags['arrayinvarname'] = true;
$this->p_vars['event_stack']->popEvent();
}
if (!$e || ($e == PARSER_EVENT_ARRAY))
$this->p_vars['varname'] .= $word;
}
if (!$this->p_flags['var_equals'])
{
if ($word != "/*" && $word != "//" && $word != "#")
{
$this->p_vars['var'] = new parserVar($this->p_vars['cur_class']);
$this->p_vars['var']->setName($this->p_vars['varname']);
}
}
if ($this->p_vars['last_word'] == "=")
{
if ($word != "/*" && $word != "//" && $word != "#")
{
$this->p_vars['var']->setValue($word);
}
}
// fix 1202772
if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))
{
$this->p_vars['var']->setValue($this->p_vars['quote_data']);
unset($this->p_vars['quote_data']);
}
if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)
{
$this->p_vars['var']->setValue($this->p_vars['function_data']);
$this->p_vars['function_data'] = false;
}
if ($this->checkEventPop($word,$pevent))
{
$this->p_vars['var']->setLineNumber($this->p_vars['linenum']);
$this->publishEvent(PHPDOCUMENTOR_EVENT_VAR,$this->p_vars['var']);
unset($this->p_vars['var']);
$this->p_flags['in_var'] = false;
$this->p_flags['var_equals'] = false;
$this->p_flags['arrayinvarname'] = false;
$this->p_vars['varname'] = '';
}
}
/**
* handler for QUOTE.
* this handler recognizes strings defined with double quotation marks (") and handles them correctly
* in any place that they legally appear in php code
*/
function handleQuote($word, $pevent)
{
if ($this->p_flags['reset_quote_data'] === true)
{
$this->p_flags['reset_quote_data'] = false;
$this->p_vars['quote_data'] = "";
}
$this->checkEventPush( $word, $pevent);
if ($word != "\"")
{
$this->p_vars['quote_data'] .= $word;
}
if ($this->checkEventPop($word,$pevent))
{
$this->p_flags['reset_quote_data'] = true;
}
}
/**
* handler for SINGLEQUOTE.
* this handler recognizes strings defined with single quotation marks (') and handles them correctly
* in any place that they legally appear in php code
*/
function handleSingleQuote($word, $pevent)
{
$this->checkEventPush( $word, $pevent);
if ($this->checkEventPop($word,$pevent))
{
if ($this->p_vars['last_word'] != "'")
{
$this->p_vars['quote_data'] = $this->p_vars['last_word'];
} else {
$this->p_vars['quote_data'] = "";
}
}
}
/**
* handler for EOFQUOTE.
* this handler recognizes strings defined with perl-style <<< EOF quotes, and handles them correctly
* in any place that they legally appear in php code
*
* an example:
* $var <<< EOF
* blah blah blah
* EOF;
*/
function handleEOFQuote($word, $pevent)
{
// echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|$this->p_vars['last_word']|\n";
if (trim($this->p_vars['last_word']) == "<<<")
{
// ok we found the keyword
//echo "Keyword == $word\n";
$this->p_vars['oldtoken'] = $this->tokens[STATE_EOFQUOTE];
$this->tokens[STATE_EOFQUOTE] = array($word);
}
else if ($this->p_vars['last_pevent'] || PARSER_EVENT_EOFQUOTE)
{
// i don't think anything will ever use this so were not going to set it
//$this->p_vars['quote_data'] = $this->p_vars['last_word'];
$this->p_vars['event_stack']->popEvent();
$this->tokens[STATE_EOFQUOTE] = $this->p_vars['oldtoken'];
}
}
/**#@-*/
/**
* Tells the parser to search for a global variable definition as
* defined by a @global type $name tag.
*
* The parser is fooled into looking for the entire global variable as a
* single token by amending the {@link $tokens} array.
*
* {@source}
* @access private
* @param string name of global variable as it appears in the source code
*/
function findGlobal($name)
{
if (!isset($this->p_vars['globaltofind']))
{
$this->p_vars['globaltofind'] = $name;
$this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($name)] = PARSER_EVENT_DEFINE_GLOBAL;
$this->tokens[STATE_PHPCODE][] = $name;
} else
{
addError(PDERROR_MULTIPLE_GLOBAL_TAGS,$this->p_vars['globaltofind'],$name);
}
}
/**#@+
* @access private
* @param string token parsed from source
* @param integer parser constant from {@link Parser.inc}
*/
/**
* handler for PHPCODE.
* this handler recognizes the
php processor directive, and begins parsing php code
*/
function handlePhpCode($word, $pevent)
{
$e = $this->checkEventPush( $word, $pevent);
if ($e == PARSER_EVENT_DOCBLOCK || $e == PARSER_EVENT_DOCBLOCK_TEMPLATE)
{
$this->wp->setWhitespace(true);
}
if (isset($this->p_vars['globaltofind']) && $e)
{
if ($e != PARSER_EVENT_DEFINE_GLOBAL && $e != PARSER_EVENT_ARRAY && $e != PARSER_EVENT_QUOTE && $e != PARSER_EVENT_SINGLEQUOTE && $e != PARSER_EVENT_COMMENT && $e != PARSER_EVENT_COMMENTBLOCK)
{
addError(PDERROR_GLOBAL_NOT_FOUND,$this->p_vars['globaltofind']);
unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);
foreach($this->tokens[STATE_PHPCODE] as $i => $notme)
if ($this->tokens[STATE_PHPCODE][$i] == $this->p_vars['globaltofind'])
unset($this->tokens[STATE_PHPCODE][$i]);
unset($this->p_vars['globaltofind']);
}
}
}
/**
* handler for global variables
*/
function handleGlobal($word, $pevent)
{
if (!$this->p_flags['in_global'])
{
$this->p_vars['linenum'] = $this->wp->linenum;
}
$this->p_flags['in_global'] = true;
$e = $this->checkEventPush($word, $pevent);
if ($this->checkEventPop($word, $pevent))
{
$this->p_flags['in_global'] = false;
$a = new parserGlobal;
$a->setDataType($this->p_vars['global_type']);
$this->p_vars['global_type'] = '';
$a->setLineNumber($this->p_vars['linenum']);
$a->setName($this->p_vars['globaltofind']);
if (isset($this->p_vars['global_val']))
$a->setValue(trim($this->p_vars['global_val']));
unset($this->p_vars['global_val']);
$this->publishEvent(PHPDOCUMENTOR_EVENT_GLOBAL,$a);
unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);
foreach($this->tokens[STATE_PHPCODE] as $i => $notme)
if ($this->tokens[STATE_PHPCODE][$i] == $this->p_vars['globaltofind'])
unset($this->tokens[STATE_PHPCODE][$i]);
unset($this->p_vars['globaltofind']);
}
}
/**
* Handles the stuff after the = in $globalvar = value
*/
function handleGlobalValue($word, $pevent)
{
if ($this->checkEventPush($word, $pevent))
{
$this->wp->setWhitespace(false);
return;
}
if (!isset($this->p_vars['global_val'])) $this->p_vars['global_val'] = '';
if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE)
{
if (!isset($this->p_vars['quote_data'])) $this->p_vars['quote_data'] = '';
$this->p_vars['global_val'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
$this->p_vars['last_pevent'] = PARSER_EVENT_GLOBAL_VALUE;
}
if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)
{
$this->p_vars['global_val'] .= $this->p_vars['function_data'];
$this->p_vars['function_data'] = false;
}
if ($word != ';')
$this->p_vars['global_val'] .= $word;
if ($this->checkEventPop($word, $pevent))
{
$this->wp->setWhitespace(false);
$this->wp->backupPos($word);
}
}
/**
* handler for FUNC_GLOBAL.
* this handler recognizes "global $var1, $var2" declarations in a function, and parses them
*/
function handleFuncGlobal($word, $pevent)
{
if ((substr(trim($word),0,1) != '$') && ($word != ',') && ($word != ';'))
{ // not a global declaration, using a variable named "$global"
$this->p_vars['event_stack']->popEvent();
return;
}
if ($this->checkEventPop($word, $pevent))
{
return;
}
if (!$this->checkEventPush($word, $pevent))
{
if ($word == ',')
{ // another variable
$this->p_vars['global_count']++;
} else
{
if (!isset($this->p_vars['globals'][$this->p_vars['global_count']]))
$this->p_vars['globals'][$this->p_vars['global_count']] = '';
if (!empty($this->p_vars['globals'][$this->p_vars['global_count']])) $this->p_vars['global_count']++;
$this->p_vars['globals'][$this->p_vars['global_count']] = trim($word);
}
}
}
/**
* handler for STATIC_VAR.
* this handler recognizes "static $var1, $var2 = 6" declarations in a function, and parses them
*/
function handleStaticVar($word, $pevent)
{
if ($this->checkEventPop($word, $pevent))
{
$this->p_vars['static_count']++;
return;
}
if (!$this->checkEventPush($word, $pevent))
{
if ($word == ',')
{
$this->p_vars['static_count']++;
return;
}
if (!isset($this->p_vars['statics'][$this->p_vars['static_count']]))
$this->p_vars['statics'][$this->p_vars['static_count']] = '';
if (!empty($this->p_vars['statics'][$this->p_vars['static_count']])) $this->p_vars['static_count']++;
$this->p_vars['statics'][$this->p_vars['static_count']] = trim($word);
}
}
/**
* handler for STATIC_VAR_VALUE.
* this handler parses the 6 in "static $var1, $var2 = 6"
*/
function handleStaticValue($word, $pevent)
{
if ($this->checkEventPush($word, $pevent))
{
return;
}
if (!isset($this->p_vars['static_val'][$this->p_vars['static_count']])) $this->p_vars['static_val'][$this->p_vars['static_count']] = '';
if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE)
{
$this->p_vars['static_val'][$this->p_vars['static_count']] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)
{
$this->p_vars['static_val'][$this->p_vars['static_count']] .= $this->p_vars['function_data'];
$this->p_vars['function_data'] = false;
}
if ($this->checkEventPop($word, $pevent))
{
$this->p_vars['static_val'][$this->p_vars['static_count']] = trim($this->p_vars['static_val'][$this->p_vars['static_count']]);
$this->wp->backupPos($word);
return;
} else $this->p_vars['static_val'][$this->p_vars['static_count']] .= $word;
}
/**
* handler for FUNCTION.
* this handler recognizes function declarations, and parses them. The body
* of the function is parsed by handleLogicBlock()
* @see handleLogicBlock()
*/
function handleFunction($word, $pevent)
{
if ($e = $this->checkEventPush( $word, $pevent))
{
if ($e == PARSER_EVENT_COMMENT || $e == PARSER_EVENT_COMMENTBLOCK) return;
}
if (!isset($this->p_vars['func'])) $this->p_vars['func'] = false;
if (! is_subclass_of($this->p_vars['func'],"parserBase"))
{
$this->p_vars['globals'] = array();
$this->p_vars['global_count'] = 0;
if ($this->p_flags['in_class'])
$this->p_vars['func'] = new parserMethod($this->p_vars['cur_class']);
else
$this->p_vars['func'] = new parserFunction;
$this->p_vars['func']->setLineNumber($this->wp->linenum);
if (trim($word) != '&')
$this->p_vars['func']->setName(trim($word));
else
$this->p_vars['func']->setReturnsReference();
} else
{
if ($this->p_vars['func']->getReturnsReference())
{
if ($this->p_vars['last_word'] == '&')
{
$this->p_vars['func']->setName(trim($word));
}
}
}
if ($this->checkEventPop($word,$pevent))
{
$this->p_vars['func']->addGlobals($this->p_vars['globals']);
$this->p_vars['func']->addStatics($this->p_vars['statics'],$this->p_vars['static_val']);
$this->p_vars['globals'] = array();
$this->p_vars['global_count'] = 0;
if ($this->p_flags['getting_source'])
{
$x = $this->wp->getSource();
$this->p_vars['func']->addSource($x);
$this->p_flags['get_source'] = false;
$this->p_flags['getting_source'] = false;
}
$this->publishEvent(PHPDOCUMENTOR_EVENT_FUNCTION,$this->p_vars['func']);
$this->p_vars['func'] = false;
}
}
/**#@-*/
/**
* Helper function for {@link handleFunctionParams()}
*
* This function adds a new parameter to the parameter list
* @access private
* @param string
*/
function endFunctionParam($word)
{
if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))
{
$this->p_vars['function_data'] .= "'".$this->p_vars['quote_data']."'";
unset($this->p_vars['quote_data']);
}
if (isset($this->p_vars['quote_data']) && ($this->p_vars['quote_data'] != '') && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE))
{
$this->p_vars['function_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
if (isset($this->p_vars['function_param']))
{
$this->p_vars['func']->addParam($this->p_vars['function_param'],$this->p_vars['function_data'], $this->p_flags['funcparam_val']);
unset($this->p_vars['function_param']);
$this->p_vars['function_data'] = '';
$this->p_flags['funcparam_val'] = false;
}
}
/**#@+
* @access private
* @param string token parsed from source
* @param integer parser constant from {@link Parser.inc}
*/
/**
* handler for FUNCTION_PARAMS.
* this handler recognizes the parameters of a function within parentheses like function(param, param = default_value)
* and parses them
* @see endFunctionParam()
*/
function handleFunctionParams($word, $pevent)
{
//echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->p_vars['last_word']."|\n";
//echo "function_param = '".$this->p_vars['function_param']."'\n";
//echo "function_data = '".$this->p_vars['function_data']."'\n";
$e1 = $this->checkEventPush( $word, $pevent);
if (!$e1)
{
if ($word == ',' || $this->checkEventPop($word,$pevent))
{
$this->endFunctionParam($word);
} elseif ($word == '=')
{
$this->p_flags['funcparam_val'] = true;
} else
{
if ($this->p_flags['funcparam_val'])
{
if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))
{
$this->p_vars['function_data'] .= "'".$this->p_vars['quote_data']."'";
unset($this->p_vars['quote_data']);
}
if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE))
{
$this->p_vars['function_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
$this->p_vars['function_data'] .= $word;
} else
{
$this->p_vars['function_param'] = $word;
}
}
}
}
/**
* javadoc-desc-compliant handler for DOCBLOCK.
* this handler recognizes @tags in DocBlocks and parses them for display.
* It also parses out unknown tags into their own array for use by the docblock
*/
function JavaDochandleDocblock($word, $pevent)
{
$e1 = $this->checkEventPush( $word, $pevent);
if (!isset($this->p_vars[$this->p_vars['docblock_type']]) || !$this->p_vars[$this->p_vars['docblock_type']])
{
$this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();
$this->p_vars['returntype'] = false;
$this->p_vars['vartype'] = false;
$this->p_flags['startdocblock'] = true;
$this->p_flags['valid_newline'] = true;
$this->p_flags['startline'] = true;
$this->p_flags['newline'] = true;
$this->p_flags['in_desc'] = true;
$this->p_flags['in_tag'] = false;
$this->p_flags['useperiod'] = false;
$this->p_vars['line'] = array();
$this->p_vars['linecount'] = 0;
}
$e = $this->checkEventPop( $word, $pevent);
if (!$e1 && !$e)
{
if ($this->p_flags['in_desc']) $this->JavaDochandleDesc($word, $pevent);
else $this->handleTags($word, $pevent);
}
if ($e)
{
if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'] = 0;
if ($this->p_vars['periodline'] > 3)
{
$this->p_flags['useperiod'] = false;
}
$this->p_vars['docblock_desc'] = new parserDesc;
// echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";
if ($this->p_vars['docblock_type'] == 'docblock')
{
if (isset($this->p_vars['docblock_template']))
{
// copy template values if not overridden
if (!$this->p_vars['docblock']->getExplicitPackage())
{
if ($p = $this->p_vars['docblock_template']->getKeyword('package'))
{
$this->p_vars['docblock']->addKeyword('package',$p);
$this->p_vars['docblock']->setExplicitPackage();
}
if ($p = $this->p_vars['docblock_template']->getKeyword('category'))
{
$this->p_vars['docblock']->addKeyword('category',$p);
$this->p_vars['docblock']->setExplicitCategory();
}
if ($p = $this->p_vars['docblock_template']->getKeyword('subpackage'))
{
$this->p_vars['docblock']->addKeyword('subpackage',$p);
}
}
$tags = $this->p_vars['docblock_template']->listTags();
foreach($tags as $tag)
{
$this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);
}
$this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);
if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params = $this->p_vars['docblock_template']->params;
}
if ($a = strpos(trim($this->p_vars['shortdesc']),'') === 0)
$this->p_vars['shortdesc'] = substr($this->p_vars['shortdesc'],strpos($this->p_vars['shortdesc'],'
') + 4);
$this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);
}
for($i = 0; $i < count($this->p_vars['line']); $i++)
{
// the line will not be set if it doesn't start with a *
if (isset($this->p_vars['line'][$i]))
$this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
}
$this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);
unset($this->p_vars['docblock_desc']);
// var_dump($this->p_vars[$this->p_vars['docblock_type']]);
// exit;
if ($this->p_vars['docblock_type'] == 'docblock')
{
$this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);
unset($this->p_vars[$this->p_vars['docblock_type']]);
$this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();
}
$this->p_flags['in_desc'] = true;
$this->p_flags['in_tag'] = false;
$this->p_flags['useperiod'] = false;
$this->p_vars['line'] = array();
$this->p_vars['linecount'] = 0;
$this->p_flags['start_docblock'] = true;
$this->p_flags['valid_newline'] = true;
$this->wp->setWhitespace(false);
}
}
/**
* handler for DOCKEYWORD_DESC.
* this handler parses the short and long description of a dockeyword
*/
function JavaDochandleDesc($word, $pevent)
{
if ($this->p_flags['valid_newline'])
{
if ($word == '@' && $this->p_flags['startline'])
{
return $this->handleTag($word, $pevent);
}
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;
}
if ($this->p_vars['last_word'] == "." && $this->p_flags['useperiod'] == false)
{
$this->p_vars['periodline'] = $this->p_vars['linecount'];
$this->p_vars['shortdesc'] = new parserDesc;
for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)
{
if (isset($this->p_vars['line'][$i]))
$this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
}
$this->p_flags['useperiod'] = true;
}
$this->p_vars['line'][$this->p_vars['linecount']]->add($word);
// debug("DESC $word");
}
$this->handleCR($word);
}
/**
* handler for DOCBLOCK.
* this handler recognizes @tags in DocBlocks and parses them for display.
* It also parses out unknown tags into their own array for use by the docblock
*/
function BetterhandleDocblock($word, $pevent)
{
$e1 = $this->checkEventPush( $word, $pevent);
if (!$this->wp->returnWhiteSpace)
{
addErrorDie(PDERROR_NEED_WHITESPACE);
}
if (!isset($this->p_vars[$this->p_vars['docblock_type']]) || !$this->p_vars[$this->p_vars['docblock_type']])
{
$this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();
$this->p_vars['returntype'] = false;
$this->p_vars['vartype'] = false;
$this->p_flags['startdocblock'] = true;
$this->p_flags['valid_newline'] = true;
$this->p_flags['startline'] = true;
$this->p_flags['newline'] = true;
$this->p_flags['in_desc'] = true;
$this->p_flags['in_tag'] = false;
$this->p_flags['useperiod'] = false;
$this->p_vars['line'] = array();
$this->p_vars['linecount'] = 0;
}
$e = $this->checkEventPop( $word, $pevent);
if (!$e1 && !$e)
{
if ($this->p_flags['in_desc']) $this->handleDesc($word, $pevent);
else $this->handleTags($word, $pevent);
}
if ($e)
{
if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'] = 0;
if ($this->p_vars['periodline'] > 3)
{
$this->p_flags['useperiod'] = false;
} else
{
for($i = 0; $i < $this->p_vars['periodline']; $i++)
{
if (isset($this->p_vars['line'][$i]))
{
if ($this->p_vars['line'][$i]->trimmedStrlen() == 0 && isset($this->p_vars['line'][$i - 1]) && $this->p_vars['line'][$i - 1]->trimmedStrlen())
{
$this->p_vars['periodline'] = $i;
}
}
}
}
// figure out the shortdesc
if ($this->p_flags['useperiod'] === false)
{
// use the first non blank line for short desc
for($i = 0; $i < count($this->p_vars['line']); $i++)
{
if (!isset($this->p_vars['line'][$i]))
$this->p_vars['line'][$i] = new parserStringWithInlineTags;
if ($this->p_vars['line'][$i]->trimmedStrlen() > 0)
{
$this->p_vars['periodline'] = $i;
$i = count($this->p_vars['line']);
}
}
// check to see if we are going to use a blank line to end the shortdesc
// this can only be in the first 4 lines
if (count($this->p_vars['line']) > 4)
{
$max = 4;
} else {
$max = count($this->p_vars['line']);
}
for($i = $this->p_vars['periodline']; $i < $max; $i++)
{
if (isset($this->p_vars['line'][$i]))
if ($this->p_vars['line'][$i]->trimmedStrlen() == 0)
{
$this->p_vars['periodline'] = $i;
$i = $max;
}
}
}
if ($this->p_vars['docblock_type'] == 'docblock')
{
$this->p_vars['shortdesc'] = new parserDesc;
for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)
{
if (isset($this->p_vars['line'][$i]))
$this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
}
$this->p_vars['periodline']++;
$this->p_vars['docblock_desc'] = new parserDesc;
if (isset($this->p_vars['docblock_template']))
{
// copy template values if not overridden
if (!$this->p_vars['docblock']->getExplicitPackage())
{
if ($p = $this->p_vars['docblock_template']->getKeyword('package'))
{
$this->p_vars['docblock']->addKeyword('package',$p);
$this->p_vars['docblock']->setExplicitPackage();
}
if ($p = $this->p_vars['docblock_template']->getKeyword('category'))
{
$this->p_vars['docblock']->addKeyword('category',$p);
$this->p_vars['docblock']->setExplicitCategory();
}
if ($p = $this->p_vars['docblock_template']->getKeyword('subpackage'))
{
$this->p_vars['docblock']->addKeyword('subpackage',$p);
}
}
$tags = $this->p_vars['docblock_template']->listTags();
foreach($tags as $tag)
{
$this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);
}
if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params = $this->p_vars['docblock_template']->params;
$this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);
}
// echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";
for($i = $this->p_vars['periodline']; $i < count($this->p_vars['line']); $i++)
{
// the line will not be set if it doesn't start with a *
if (isset($this->p_vars['line'][$i]))
$this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
}
} else
{
$this->p_vars['shortdesc'] = new parserDesc;
for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)
{
if (isset($this->p_vars['line'][$i]))
$this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);
}
$this->p_vars['periodline']++;
$this->p_vars['docblock_desc'] = new parserDesc;
for($i=$this->p_vars['periodline']; $i < count($this->p_vars['line']); $i++)
{
if (isset($this->p_vars['line'][$i]))
$this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);
}
}
$this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);
$this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);
unset($this->p_vars['docblock_desc']);
// var_dump($this->p_vars[$this->p_vars['docblock_type']]);
// exit;
if ($this->p_vars['docblock_type'] == 'docblock')
{
$this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);
unset($this->p_vars[$this->p_vars['docblock_type']]);
$this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();
} else
{
$this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE,$this->p_vars[$this->p_vars['docblock_type']]);
}
$this->p_flags['in_desc'] = true;
$this->p_flags['in_tag'] = false;
$this->p_flags['useperiod'] = false;
$this->p_vars['line'] = array();
$this->p_vars['linecount'] = 0;
$this->p_flags['start_docblock'] = true;
$this->p_flags['valid_newline'] = true;
$this->wp->setWhitespace(false);
$this->p_vars['docblock_type'] = 'docblock';
}
}
/**
* Handles docblock templates
* @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate
*/
function handleDocBlockTemplate($word, $pevent)
{
$this->p_vars['docblock_type'] = 'docblock_template';
$this->p_vars['event_stack']->popEvent();
$this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCBLOCK);
// fool the docblock handler into thinking everything is totally normal
$this->p_vars['last_word'] = '/**';
$pevent = PARSER_EVENT_DOCBLOCK;
$this->BetterhandleDocBlock($word, $pevent);
}
/**
* Handles closing docblock templates /**#@-* /
* @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate
*/
function handleEndDocBlockTemplate($word, $pevent)
{
unset($this->p_vars['docblock_template']);
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE);
$this->p_vars['event_stack']->popEvent();
}
/**#@-*/
/**
* Handles a new line in a DocBlock
* @param string token containing a newline \n
* @access private
*/
function handleCR($word)
{
$this->laststart = $this->p_flags['startline'];
if ($word == "\n" || $word == ".\n")
{
$this->p_flags['start_docblock'] = false;
$this->p_flags['newline'] = true;
$this->p_flags['valid_newline'] = false;
if ($this->p_flags['in_desc'] && !$this->p_flags['useperiod'])
{
if ($word == ".\n")
{
$this->p_flags['useperiod'] = true;
$this->p_vars['periodline'] = $this->p_vars['linecount'];
}
}
} else
{
if ($this->p_flags['valid_newline'] && strlen(trim($word)))
{
$this->p_flags['startline'] = false;
}
if ($this->p_flags['newline'] && ($word == '*' || $this->p_flags['start_docblock']))
{
$this->p_flags['newline'] = false;
$this->p_flags['valid_newline'] = true;
if (!$this->p_flags['start_docblock'])
$this->p_vars['linecount']++;
$this->p_flags['startline'] = true;
$justset = true;
// debug('valid newline');
}
}
}
/**
* handler for DOCKEYWORD_DESC.
* this handler parses the short and long description of a dockeyword
* @access private
*/
function handleDesc($word, $pevent)
{
// echo "|$word|\n";
if ($this->p_flags['valid_newline'])
{
if ($word == '@' && $this->p_flags['startline'])
{
return $this->handleTag($word, $pevent);
}
if ($this->p_vars['last_word'] == ". " || $this->p_vars['last_word'] == ".\t")
{
$this->p_flags['useperiod'] = true;
$this->p_vars['periodline'] = $this->p_vars['linecount'];
$this->p_vars['linecount']++;
}
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;
}
if ($this->p_flags['startline'])
{
if ($word[0] == ' ') $word = substr($word,1);
// $word = ltrim($word," \t");
}
if ($word != '') $this->p_vars['line'][$this->p_vars['linecount']]->add($word);
// debug("DESC $word");
}
$this->handleCR($word);
}
/**#@+
* @access private
* @param string token parsed from source
* @param integer parser constant from {@link Parser.inc}
*/
/**
* handler for DOCKEYWORD_TAGS.
* this handler recognizes @tags in DocBlocks and parses them for display
* I think this may be unused. We'll delete from 1.1 if so
*/
function handleTags($word, $pevent)
{
if ($this->p_flags['valid_newline'])
{
// debug("TAGS $word");
}
$this->handleCR($word);
}
/**
* handler for DOCKEYWORD.
* this handler recognizes @tags in DocBlocks and parses them for display
*/
function handleTag($word, $pevent)
{
if ($this->p_flags['in_desc'] && !$this->p_flags['valid_newline'])
{
$this->p_vars['event_stack']->popEvent();
return $this->handleDesc($word, $pevent);
}
// if ($this->p_vars['last_word'] == '@') fancy_debug('here'.$word,$this->p_flags['startline'],$this->p_flags['in_tag']);
if ($this->p_vars['tagname'] == 'author')
{
if ($word == '<')
{
$this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCKEYWORD_EMAIL);
return $this->handleDockeywordEmail($word, $pevent);
}
}
if ($this->checkEventPush( $word, $pevent)) return;
if ($this->p_vars['last_word'] == '@' && !$this->p_flags['startline'] && $this->p_flags['in_desc'])
{
// fix 1203445
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;
}
$this->p_vars['event_stack']->popEvent();
$this->p_vars['line'][$this->p_vars['linecount']]->add('@');
return $this->handleDesc($word, $pevent);
} elseif($this->p_vars['last_word'] == '@' && !strlen(trim($word)) && empty($this->p_vars['tagname']) && $this->p_flags['in_desc'])
{
// fix 1203445
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;
}
$pevent = $this->p_vars['event_stack']->popEvent();
$this->p_vars['line'][$this->p_vars['linecount']]->add('@');
return $this->handleDesc($word, $pevent);
}
if ($word == '@' && $this->p_flags['startline'] && $this->p_flags['in_tag'])
{
$this->wp->backupPos($word);
$white = $this->wp->returnWhiteSpace;
$this->wp->setWhitespace(true);
$word1 = $this->wp->getWord();
$this->wp->backupPos($word1);
if (strlen(trim($word1)))
{
$this->endTag();
}
$this->wp->getWord();
$this->wp->setWhitespace($white);
}
$this->p_flags['in_tag'] = true;
$e = $this->checkEventPop($word, $pevent);
if (!$e)
{
if ($this->p_flags['valid_newline'])
{
if (($this->p_flags['startline'] || $this->laststart) && $word != '@')
{
if ($this->p_vars['last_word'] == '@')
{
// debug("TAGSTART $word");
$this->p_flags['in_tag'] = true;
$this->p_vars['tagname'] = $word;
$this->p_flags['startline'] = false;
$this->p_vars['tag_value'] = new parserStringWithInlineTags;
} else
{
// debug("TAG1 $word");
if (isset($this->tagHandlers[$this->p_vars['tagname']]))
$handler = $this->tagHandlers[$this->p_vars['tagname']];
else $handler = $this->tagHandlers['*'];
$this->$handler($word);
}
} else
{
if (empty($this->p_vars['tagname']))
{
if ($this->p_flags['in_desc'])
{
$this->p_flags['in_tag'] = false;
// fix 1203445
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] =
new parserStringWithInlineTags;
}
$this->p_vars['line'][$this->p_vars['linecount']]->add('@');
$this->p_vars['event_stack']->popEvent();
$this->handleCR($word);
return $this->handleDesc($word, $pevent);
}
}
// debug("TAG2 $word");
if (isset($this->tagHandlers[$this->p_vars['tagname']]))
$handler = $this->tagHandlers[$this->p_vars['tagname']];
else $handler = $this->tagHandlers['*'];
$this->$handler($word);
}
}
$this->handleCR($word);
}
$this->p_flags['in_desc'] = false;
if ($e)
{
$this->endTag();
$this->wp->setWhitespace(false);
// walk back a word
$this->wp->backupPos($word);
$this->wp->setWhitespace(true);
}
}
/**#@-*/
/**
* Called to clean up at the end of parsing a @tag in a docblock
*/
function endTag()
{
if (isset($this->tagHandlers[$this->p_vars['tagname']]))
$handler = $this->tagHandlers[$this->p_vars['tagname']];
else $handler = $this->tagHandlers['*'];
$this->$handler(false);
$this->p_vars['tagname'] = '';
$this->p_flags['startline'] = true;
// debug("ENDTAG");
}
/**#@+
* Tag Handlers
* @param string
*/
/**
* Handles all standard tags that only have a description
*/
function defaultTagHandler($word)
{
if ($word !== false)
{
$this->p_vars['tag_value']->add($word);
} else
{
$this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
}
}
/**
* Handles tags like '@filesource' that only work in PHP 4.3.0+
*/
function invalidTagHandler($word)
{
if ($word === false)
{
addError(PDERROR_TAG_NOT_HANDLED,$this->p_vars['tagname']);
}
}
/**
* handles @package
* @tutorial tags.package.pkg
*/
function packageTagHandler($word)
{
if ($word !== false)
{
$this->p_vars['tag_value']->add($word);
} else
{
$this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
$this->p_vars[$this->p_vars['docblock_type']]->setExplicitPackage();
}
}
/**
* handles @example
* @tutorial tags.example.pkg
*/
function exampleTagHandler($word)
{
if ($word !== false)
{
$this->p_vars['tag_value']->add($word);
} else
{
$this->p_vars[$this->p_vars['docblock_type']]->addExample($this->p_vars['tag_value'], $this->p_vars['parsepath']);
}
}
/**
* handles @category
* @tutorial tags.category.pkg
*/
function categoryTagHandler($word)
{
if ($word !== false)
{
$this->p_vars['tag_value']->add($word);
} else
{
$this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);
$this->p_vars[$this->p_vars['docblock_type']]->setExplicitCategory();
}
}
/**
* handles @global
* @tutorial tags.global.pkg
*/
function globalTagHandler($word)
{
if ($word !== false)
{
// no data yet
$a = trim($this->p_vars['tag_value']->getString());
if (empty($a))
{
// not an empty word
if (trim($word) != '')
{
if (!empty($this->p_vars['global_type']))
{
if (!$this->p_flags['define_global'] && !$this->p_flags['function_global'])
{
// @global type $GLOBALVARNAME ?
if (substr($word,0,1) == '$')
{
$this->p_flags['define_global'] = true;
$this->p_flags['function_global'] = false;
$this->p_vars['find_global'] = $word;
} else
{ // function @global type description
$this->p_flags['function_global'] = true;
$this->p_flags['define_global'] = false;
$this->p_vars['tag_value']->add($word);
}
} else
{
if ($this->p_flags['define_global'])
{
$this->p_vars['find_global'] .= $word;
} elseif($this->p_flags['function_global'])
{
// description, to be added to the tag
$this->p_vars['tag_value']->add($word);
}
}
} else
{
$this->p_vars['global_type'] = $word;
}
} else $this->p_vars['tag_value']->add($word); // add whitespace to the tag description
} else
{ // tag_value has data, must be a function @global
$this->p_vars['tag_value']->add($word);
}
} else
{ // endtag
if ($this->p_flags['define_global'])
{
$this->findGlobal($this->p_vars['find_global']);
}
elseif ($this->p_flags['function_global'])
{
$this->p_vars[$this->p_vars['docblock_type']]->addFuncGlobal($this->p_vars['global_type'],$this->p_vars['tag_value']);
$this->p_vars['global_type'] = '';
}
else
{
addError(PDERROR_MALFORMED_GLOBAL_TAG);
}
$this->p_vars['find_global'] = '';
$this->p_flags['define_global'] = false;
$this->p_flags['function_global'] = false;
}
}
/**
* handles @staticvar
* @tutorial tags.staticvar.pkg
*/
function staticvarTagHandler($word)
{
if ($word !== false)
{
if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);
else
{
if (!$this->p_vars['paramname'])
{
if (substr(trim($word),0,1) == "$")
$this->p_vars['paramname'] = trim($word);
else $this->p_vars['tag_value']->add($word);
} else
{
if (0)//strtolower($this->p_vars['paramtype']) == 'object')
{
if (strlen(trim($word)))
$this->p_vars['paramname'] = trim($word);
} else $this->p_vars['tag_value']->add($word);
}
}
} else
{
if (!$this->p_vars['paramname'])
$this->p_vars[$this->p_vars['docblock_type']]->addStaticVar(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);
else
$this->p_vars[$this->p_vars['docblock_type']]->addStaticVar($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);
$this->p_vars['paramname'] = false;
$this->p_vars['returntype'] = false;
}
}
/**
* handles @uses
* @tutorial tags.uses.pkg
*/
function usesTagHandler($word)
{
if ($word !== false)
{
if (!$this->p_vars['seelement']) $this->p_vars['seelement'] = trim($word);
else
{
$this->p_vars['tag_value']->add($word);
}
} else
{
$see = new parserStringWithInlineTags;
$see->add($this->p_vars['seelement']);
$this->p_vars[$this->p_vars['docblock_type']]->addUses($see,$this->p_vars['tag_value']);
$this->p_vars['seelement'] = false;
}
}
/**
* handles @param
* @tutorial tags.param.pkg
*/
function paramTagHandler($word)
{
if ($word !== false)
{
if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);
else
{
if (!$this->p_vars['paramname'])
{
if (substr(trim($word),0,1) == "$" || substr(trim($word),0,2) == "&$")
$this->p_vars['paramname'] = trim($word);
else $this->p_vars['tag_value']->add($word);
} else
{
if (0)//strtolower($this->p_vars['paramtype']) == 'object')
{
if (strlen(trim($word)))
$this->p_vars['paramname'] = trim($word);
} else $this->p_vars['tag_value']->add($word);
}
}
} else
{
if (!$this->p_vars['paramname'])
$this->p_vars[$this->p_vars['docblock_type']]->addParam(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);
else
$this->p_vars[$this->p_vars['docblock_type']]->addParam($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);
$this->p_vars['paramname'] = false;
$this->p_vars['returntype'] = false;
}
}
/**
* handles @return
* @tutorial tags.return.pkg
*/
function returnTagHandler($word)
{
if ($word !== false)
{
if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);
else
{
if (strtolower($this->p_vars['returntype']) == 'object')
{
if (strlen(trim($word)))
$this->p_vars['returntype'] = trim($word);
} else $this->p_vars['tag_value']->add($word);
}
} else
{
$this->p_vars[$this->p_vars['docblock_type']]->addReturn($this->p_vars['returntype'],$this->p_vars['tag_value']);
$this->p_vars['returntype'] = false;
}
}
/**
* handles @var
* @tutorial tags.var.pkg
*/
function varTagHandler($word)
{
if ($word)
{
if (!$this->p_vars['vartype']) $this->p_vars['vartype'] = trim($word);
else
{
if (strtolower($this->p_vars['vartype']) == 'object')
{
if (strlen(trim($word)))
$this->p_vars['vartype'] = trim($word);
}
else $this->p_vars['tag_value']->add($word);
}
} elseif ($word === false)
{
$this->p_vars[$this->p_vars['docblock_type']]->addVar($this->p_vars['vartype'],$this->p_vars['tag_value']);
$this->p_vars['vartype'] = false;
}
}
/**
* Handles @property(-read or -write) and @method magic tag
*/
function propertyTagHandler( $word )
{
if ( $word !== false )
{
if ( !$this->p_vars['returntype'] )
$this->p_vars['returntype'] = trim( $word );
else
{
if ( !$this->p_vars['property_name'] )
{
if ( substr( trim( $word ), 0, 1 ) == "$"
|| substr(trim($word), 0, 2) == "&$"
|| substr(trim($word), -2, 2) == "()"
)
$this->p_vars['property_name'] = trim( $word );
else
$this->p_vars['tag_value']->add( $word );
}
else
{
$this->p_vars['tag_value']->add( $word );
}
}
}
else
{
$this->p_vars[$this->p_vars['docblock_type']]->addProperty( $this->p_vars['tagname'],
$this->p_vars['property_name'],
$this->p_vars['returntype'],
$this->p_vars['tag_value'] );
$this->p_vars['property_name'] = false;
$this->p_vars['returntype'] = false;
}
}
/**#@-*/
/** @access private */
function getSource()
{
$this->p_flags['get_source'] = true;
}
/**#@+
* @access private
* @param string token parsed from source
* @param integer parser constant from {@link Parser.inc}
*/
/**
* handler for DOCKEYWORD_EMAIL.
* this handler recognizes angle brackets < and > surrounding an email address in an @author tag,
* and returns a mailto: hyperlink
*/
function handleDockeywordEmail($word, $pevent)
{
//echo $this->wp->getPos() . ": |$word|\n";
if (!$this->checkEventPop($word,$pevent) && $word != "<")
{
if (strstr($word,"@"))
{
$this->p_vars['tag_value']->add('<');
$this->p_vars['tag_value']->add(new parserLinkInlineTag("mailto:$word",$word));
$this->p_vars['tag_value']->add('>');
} else {
$this->p_vars['tag_value']->add("<$word>");
}
}
}
/**
* handler for INLINE_DOCKEYWORD.
* this handler recognizes {@inline tags} like link, and parses them, replacing them directly
* in the text flow with their output.
*/
function handleInlineDockeyword($word, $pevent)
{
// echo $this->wp->getPos() . ": |$word|\n";
// echo "docktype: $this->p_vars['inline_dockeyword_type']\n";
if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = false;
if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data'] = '';
if (!$this->p_vars['inline_dockeyword_type'])
{
if (in_array($word,$this->allowableInlineTags))
{
if ($word == '}')
$this->p_vars['inline_dockeyword_type'] = '';
else
$this->p_vars['inline_dockeyword_type'] = strtolower($word);
$this->p_vars['whitesp'] = $this->wp->returnWhiteSpace;
$this->wp->setWhiteSpace(true);
} else {
if ($this->p_flags['in_desc'])
{
// fix 1203445
if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))
{
$this->p_vars['line'][$this->p_vars['linecount']] =
new parserStringWithInlineTags;
}
if ($word == '}')
{
$this->p_vars['line'][$this->p_vars['linecount']]->add('{@');
} else
{
$this->p_vars['line'][$this->p_vars['linecount']]->add('{@'.$word);
}
} elseif($this->p_flags['in_tag'])
{
if ($word == '}')
$this->p_vars['tag_value']->add('{@'.$word);
else
$this->p_vars['tag_value']->add('{@'.$word);
}
$this->p_vars['event_stack']->popEvent();
$this->p_vars['inline_dockeyword_type'] = false;
$this->p_vars['inline_dockeyword_data'] = '';
return;
}
} else
{
if ($word != "}")
{
$this->p_vars['inline_dockeyword_data'] .= $word;
}
}
if ($this->checkEventPop($word,$pevent))
{
$this->wp->setWhiteSpace($this->p_vars['whitesp']);
if ($this->p_vars['inline_dockeyword_type']=='link')
{
// support hyperlinks of any protocol
if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:') === 0))
{
// if there is more than 1 parameter, the stuff after the space is the hyperlink text
if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))
{
$i1 = strpos(trim($this->p_vars['inline_dockeyword_data']),' ') + 1;
$link = substr(trim($this->p_vars['inline_dockeyword_data']),0,$i1 - 1);
$text = substr(trim($this->p_vars['inline_dockeyword_data']),$i1);
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($link,$text);
// ''.$text.'';
}
else
{
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
// ''.$this->p_vars['inline_dockeyword_data'].'';
} else
{
if (!strpos($this->p_vars['inline_dockeyword_data'],','))
{
$testp = explode('#',$this->p_vars['inline_dockeyword_data']);
if (count($testp) - 1)
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$testp[1]);
else
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
} else
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
}
if ($this->p_vars['inline_dockeyword_type'] == 'tutorial')
{
$this->p_vars['inline_dockeyword_data'] = new parserTutorialInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
if ($this->p_vars['inline_dockeyword_type'] == 'source')
{
$this->getSource();
$this->p_vars['inline_dockeyword_data'] = new parserSourceInlineTag($this->p_vars['inline_dockeyword_data']);
}
if ($this->p_vars['inline_dockeyword_type'] == 'inheritdoc')
{
$this->p_vars['inline_dockeyword_data'] = new parserInheritdocInlineTag();
}
if ($word == '*/')
{
if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = '';
if (!isset($this->p_vars['tagname'])) $this->p_vars['tagname'] = '';
if (!isset($this->p_vars['tag_value']) || !is_object($this->p_vars['tag_value'])) $this->p_vars['tag_value'] = new parserStringWithInlineTags;
addError(PDERROR_UNTERMINATED_INLINE_TAG,$this->p_vars['inline_dockeyword_type'],$this->p_vars['tagname'],'@'.$this->p_vars['tagname'].' '.$this->p_vars['tag_value']->getString());
// when we add the error class, raise error here: we reached the end of the docblock
$this->wp->backupPos($word);
}
if ($this->p_flags['in_desc'])
{
$this->p_vars['line'][$this->p_vars['linecount']]->add($this->p_vars['inline_dockeyword_data']);
$this->p_vars['inline_dockeyword_type'] = false;
$this->p_vars['inline_dockeyword_data'] = '';
}
elseif ($this->p_flags['in_tag'])
{
$this->p_vars['tag_value']->add($this->p_vars['inline_dockeyword_data']);
$this->p_vars['inline_dockeyword_type'] = false;
$this->p_vars['inline_dockeyword_data'] = '';
}
}
}
/**
* handler for INCLUDE.
* this handler recognizes include/require/include_once/include_once statements, and publishes the
* data to Render
*/
function handleInclude($word, $pevent)
{
if (!$this->p_flags['in_include'])
{
$this->p_vars['linenum'] = $this->wp->linenum;
}
$this->p_flags['in_include'] = true;
$a = $this->checkEventPush( $word, $pevent);
if (!$this->p_flags['includename_isset'])
{
$this->p_flags['includename_isset'] = true;
$this->p_vars['include_name'] = $this->p_vars['last_word'];
if ($a)
$this->p_vars['include_value'] = '';
else
$this->p_vars['include_value'] = $word;
unset($this->p_vars['quote_data']);
} else
{
if (!$a)
{
if (empty($this->p_vars['include_params_data']))
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['include_value'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
if ($word != ';')
$this->p_vars['include_value'] .= $word;
}
} else
{
$this->p_vars['include_params_data'] = '';
}
}
if ($this->checkEventPop($word,$pevent))
{
$this->p_vars['include'] = new parserInclude;
$this->p_vars['include']->setLineNumber($this->p_vars['linenum']);
$this->p_flags['in_include'] = false;
$this->p_vars['include']->setName($this->p_vars['include_name']);
$this->p_vars['include']->setValue($this->p_vars['include_value']);
$this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE,$this->p_vars['include']);
$this->p_flags['includename_isset'] = false;
unset($this->p_vars['include']);
unset($this->p_vars['include_name']);
unset($this->p_vars['include_value']);
unset($this->p_vars['include_params_data']);
}
}
/**
* handler for INCLUDE_PARAMS.
* this handler parses the contents of ( ) in include/require/include_once/include_once statements
*/
function handleIncludeParams($word, $pevent)
{
$this->checkEventPush( $word, $pevent);
$this->p_flags['include_parens'] = true;
if(!isset($this->p_vars['include_params_data'])) $this->p_vars['include_params_data'] = '';
if ($this->checkEventPop($word,$pevent))
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['include_value'] = $this->p_vars['include_params_data'].'"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
} else {
if (!empty($this->p_vars['include_params_data']))
$this->p_vars['include_value'] = $this->p_vars['include_params_data'];
else
$this->p_vars['include_value'] = trim($this->p_vars['last_word']);
}
}
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['include_params_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
if (($word != "'") && ($word != '"'))
$this->p_vars['include_params_data'] .= $word;
}
/**
* handler for INCLUDE_PARAMS_PARENTHESIS.
* this handler takes all parenthetical statements within file in:
* include statement include(file), and handles them properly
*/
function handleIncludeParamsParenthesis($word, $pevent)
{
if (isset($this->p_vars['quote_data']))
{
$this->p_vars['include_params_data'] .= '"'.$this->p_vars['quote_data'].'"';
unset($this->p_vars['quote_data']);
}
$this->p_vars['include_params_data'] .= $word;
$this->checkEventPush( $word, $pevent);
$this->checkEventPop( $word, $pevent);
}
/**#@-*/
/**
* this function checks whether parameter $word is a token for pushing a new event onto the Event Stack.
* @return mixed returns false, or the event number
*/
function checkEventPush($word,$pevent)
{
$e = false;
if (isset($this->pushEvent[$pevent]))
{
if (isset($this->pushEvent[$pevent][strtolower($word)]))
$e = $this->pushEvent[$pevent][strtolower($word)];
}
if ($e)
{
$this->p_vars['event_stack']->pushEvent($e);
return $e;
} else {
return false;
}
}
/**
* this function checks whether parameter $word is a token for popping the current event off of the Event Stack.
* @return mixed returns false, or the event number popped off of the stack
*/
function checkEventPop($word,$pevent)
{
if (!isset($this->popEvent[$pevent])) return false;
if (in_array(strtolower($word),$this->popEvent[$pevent]))
{
return $this->p_vars['event_stack']->popEvent();
} else {
return false;
}
}
/**
* setup the parser tokens, and the pushEvent/popEvent arrays
* @see $tokens, $pushEvent, $popEvent
*/
function setupStates()
{
$this->tokens[STATE_PHPCODE] = array(" ", "\t",";","?>","","/**#@+","/**#@-*/","/**", "//","/*","#","\r\n","\n","\r","(",'<<<','"',"'");
$this->tokens[STATE_QUOTE] = array("\\\"","\\\\","\"");
$this->tokens[STATE_LOGICBLOCK] = array("{","}","\"","'","/*","//","#","?>","",'<<<','global','static');
$this->tokens[STATE_FUNC_GLOBAL] = array("\"","'","/*","//","#",";",",");
$this->tokens[STATE_STATIC_VAR] = array("\"","'","/*","//","#",";",",",'=','array');
$this->tokens[STATE_STATIC_VAR_VALUE] = array("/*","//","#"," ","\t",";","=","\"","'","array",",");
$this->tokens[STATE_NOEVENTS] = array("');
$this->tokens[STATE_COMMENTBLOCK] = array("*/","\n");
$this->tokens[STATE_COMMENT] = array("\r\n","\r","\n");
$this->tokens[STATE_DEFINE] = array(" ","(",";");
$this->tokens[STATE_DEFINE_PARAMS] = array("/*","//","#",",",")"," ","'","\"","(");
$this->tokens[STATE_DEFINE_PARAMS_PARENTHESIS] = array("(","'","\"",")");
$this->tokens[STATE_FUNCTION_PARAMS] = array("/*","//","#","\"",",",")","="," ","'","(");
$this->tokens[STATE_SINGLEQUOTE] = array("'","\\'","\\\\");
$this->tokens[STATE_CLASS] = array(" ", "\t", "?>", "", ";", "}", "{",
"/**#@+", "/**#@-*/", "/**", "//", "/*", "#",
"\r\n", "\n", "\r","(");
$this->tokens[STATE_DOCBLOCK] = array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');
$this->tokens[STATE_DOCBLOCK_TEMPLATE] = array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');
$this->tokens[STATE_DOCKEYWORD] = array("@","*/","*","\n","\r\n","\r","\t"," ","<",">",'{@');
$this->tokens[STATE_INLINE_DOCKEYWORD] = array("{@","}","\t"," ","*/");
$this->tokens[STATE_DOCKEYWORD_EMAIL] = array(">","\n","\r\n","\r");
$this->tokens[STATE_VAR] = array("/*","//","#"," ","\t",";","=",",","\"","'","array");
$this->tokens[STATE_GLOBAL] = array("/*","//","#"," ","\t",";","=","\"","'");
$this->tokens[STATE_GLOBAL_VALUE] = array("/*","//","#"," ","\t",";","=","\"","'","array");
$this->tokens[STATE_ARRAY] = array("/*","//","#","(",")","\"","'","array");
$this->tokens[STATE_FUNCTION] = array("(","{","}"," ","\t","&","/*","//","#");
$this->tokens[STATE_OUTPHP] = array("');
$this->tokens[STATE_EOFQUOTE] = array(" ","\t","\n");
$this->tokens[STATE_ESCAPE] = false;// this tells the word parser to just cycle
$this->tokens[STATE_INCLUDE] = array(" ","(",";","'",'"');
$this->tokens[STATE_INCLUDE_PARAMS] = array("/*",")"," ","'","\"","(");
$this->tokens[STATE_INCLUDE_PARAMS_PARENTHESIS] = array("(","'","\"",")");
// For each event word to event mapings
$this->pushEvent[PARSER_EVENT_QUOTE] =
array(
"\\" => PARSER_EVENT_ESCAPE
);
$this->popEvent[PARSER_EVENT_QUOTE] = array("\"");
##########################
$this->pushEvent[PARSER_EVENT_LOGICBLOCK] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT,
"global" => PARSER_EVENT_FUNC_GLOBAL,
"static" => PARSER_EVENT_STATIC_VAR,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"{" => PARSER_EVENT_LOGICBLOCK,
"?>" => PARSER_EVENT_OUTPHP,
"" => PARSER_EVENT_OUTPHP,
"<<<" => PARSER_EVENT_EOFQUOTE
);
$this->popEvent[PARSER_EVENT_LOGICBLOCK] = array("}");
##########################
$this->pushEvent[PARSER_EVENT_FUNC_GLOBAL] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT,
"/*" => PARSER_EVENT_COMMENTBLOCK,
);
$this->popEvent[PARSER_EVENT_FUNC_GLOBAL] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_STATIC_VAR] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"=" => PARSER_EVENT_STATIC_VAR_VALUE,
);
$this->popEvent[PARSER_EVENT_STATIC_VAR] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_STATIC_VAR_VALUE] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"array" => PARSER_EVENT_ARRAY,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_STATIC_VAR_VALUE] = array(";",",");
##########################
$this->pushEvent[PARSER_EVENT_NOEVENTS] =
array(
" PARSER_EVENT_PHPCODE,
"" => PARSER_EVENT_PHPCODE,
'" => PARSER_EVENT_OUTPHP,
);
##########################
$this->pushEvent[PARSER_EVENT_FUNCTION] =
array(
"(" => PARSER_EVENT_FUNCTION_PARAMS,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"{" => PARSER_EVENT_LOGICBLOCK
);
$this->popEvent[PARSER_EVENT_FUNCTION] = array("}");
##########################
$this->pushEvent[PARSER_EVENT_DOCBLOCK] =
array(
"@" => PARSER_EVENT_DOCKEYWORD,
"{@" => PARSER_EVENT_INLINE_DOCKEYWORD
);
$this->popEvent[PARSER_EVENT_DOCBLOCK] = array("*/");
##########################
$this->pushEvent[PARSER_EVENT_DOCBLOCK_TEMPLATE] =
array(
"@" => PARSER_EVENT_DOCKEYWORD,
"{@" => PARSER_EVENT_INLINE_DOCKEYWORD
);
$this->popEvent[PARSER_EVENT_DOCBLOCK_TEMPLATE] = array("*/");
##########################
$this->pushEvent[PARSER_EVENT_CLASS] =
array(
"function" => PARSER_EVENT_FUNCTION,
"var" => PARSER_EVENT_VAR,
"/**" => PARSER_EVENT_DOCBLOCK,
"/**#@+" => PARSER_EVENT_DOCBLOCK_TEMPLATE,
"/**#@-*/" => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
"//" => PARSER_EVENT_COMMENT,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"#" => PARSER_EVENT_COMMENT,
"?>" => PARSER_EVENT_OUTPHP,
"" => PARSER_EVENT_OUTPHP,
);
$this->popEvent[PARSER_EVENT_CLASS] = array("}");
##########################
$this->pushEvent[PARSER_EVENT_DEFINE] =
array(
"/*" => PARSER_EVENT_COMMENTBLOCK,
"(" => PARSER_EVENT_DEFINE_PARAMS
);
$this->popEvent[PARSER_EVENT_DEFINE] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_INCLUDE] =
array(
"/*" => PARSER_EVENT_COMMENTBLOCK,
"(" => PARSER_EVENT_INCLUDE_PARAMS,
"'" => PARSER_EVENT_SINGLEQUOTE,
'"' => PARSER_EVENT_QUOTE,
);
$this->popEvent[PARSER_EVENT_INCLUDE] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_DEFINE_PARAMS] =
array(
"(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
"'" => PARSER_EVENT_SINGLEQUOTE,
'"' => PARSER_EVENT_QUOTE,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_DEFINE_PARAMS] = array(")");
##########################
$this->pushEvent[PARSER_EVENT_INCLUDE_PARAMS] =
array(
"(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
"'" => PARSER_EVENT_SINGLEQUOTE,
'"' => PARSER_EVENT_QUOTE,
);
$this->popEvent[PARSER_EVENT_INCLUDE_PARAMS] = array(")");
##########################
$this->pushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =
array(
"(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
"'" => PARSER_EVENT_SINGLEQUOTE,
'"' => PARSER_EVENT_QUOTE,
);
$this->popEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] = array(")");
##########################
$this->pushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =
array(
"(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
"'" => PARSER_EVENT_SINGLEQUOTE,
'"' => PARSER_EVENT_QUOTE,
);
$this->popEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] = array(")");
##########################
$this->pushEvent[PARSER_EVENT_VAR] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"array" => PARSER_EVENT_ARRAY,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_VAR] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_DEFINE_GLOBAL] =
array(
"=" => PARSER_EVENT_GLOBAL_VALUE,
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_DEFINE_GLOBAL] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_GLOBAL_VALUE] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"array" => PARSER_EVENT_ARRAY,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_GLOBAL_VALUE] = array(";");
##########################
$this->pushEvent[PARSER_EVENT_COMMENT] =
array(
"\\" => PARSER_EVENT_ESCAPE
);
$this->popEvent[PARSER_EVENT_COMMENT] = array("\n");
##########################
$this->popEvent[PARSER_EVENT_COMMENTBLOCK] = array("*/");
##########################
$this->pushEvent[PARSER_EVENT_SINGLEQUOTE] =
array(
"\\" => PARSER_EVENT_ESCAPE
);
$this->popEvent[PARSER_EVENT_SINGLEQUOTE] = array("'");
##########################
$this->pushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"array" => PARSER_EVENT_ARRAY,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(")");
##########################
$this->pushEvent[PARSER_EVENT_DOCKEYWORD] =
array(
// "<" => PARSER_EVENT_DOCKEYWORD_EMAIL,
"{@" => PARSER_EVENT_INLINE_DOCKEYWORD,
);
$this->popEvent[PARSER_EVENT_DOCKEYWORD] = array("*/");
##########################
$this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORD] = array("}","*/");
##########################
$this->popEvent[PARSER_EVENT_OUTPHP] = array("');
##########################
$this->popEvent[PARSER_EVENT_DOCKEYWORD_EMAIL] = array(">","\n");
##########################
$this->pushEvent[PARSER_EVENT_ARRAY] =
array(
"\"" => PARSER_EVENT_QUOTE,
"'" => PARSER_EVENT_SINGLEQUOTE,
"array" => PARSER_EVENT_ARRAY,
"/*" => PARSER_EVENT_COMMENTBLOCK,
"//" => PARSER_EVENT_COMMENT,
"#" => PARSER_EVENT_COMMENT
);
$this->popEvent[PARSER_EVENT_ARRAY] = array(")");
##########################
}
/**
* tell the parser's WordParser {@link $wp} to set up tokens to parse words by.
* tokens are word separators. In English, a space or punctuation are examples of tokens.
* In PHP, a token can be a ;, a parenthesis, or even the word "function"
* @param $value integer an event number
* @see WordParser
*/
function configWordParser($e)
{
$this->wp->setSeperator($this->tokens[($e + 100)]);
}
/**
* Debugging function, takes an event number and attempts to return its name
* @param $value integer an event number
*/
function getParserEventName ($value)
{
$lookup = array(
PARSER_EVENT_NOEVENTS => "PARSER_EVENT_NOEVENTS",
PARSER_EVENT_PHPCODE => "PARSER_EVENT_PHPCODE",
PARSER_EVENT_DOCBLOCK => "PARSER_EVENT_DOCBLOCK",
PARSER_EVENT_FUNCTION => "PARSER_EVENT_FUNCTION",
PARSER_EVENT_CLASS => "PARSER_EVENT_CLASS",
PARSER_EVENT_DEFINE => "PARSER_EVENT_DEFINE",
PARSER_EVENT_DEFINE_PARAMS => "PARSER_EVENT_DEFINE_PARAMS",
PARSER_EVENT_COMMENT => "PARSER_EVENT_COMMENT",
PARSER_EVENT_COMMENTBLOCK => "PARSER_EVENT_COMMENTBLOCK",
PARSER_EVENT_ESCAPE => "PARSER_EVENT_ESCAPE",
PARSER_EVENT_QUOTE => "PARSER_EVENT_QUOTE",
PARSER_EVENT_FUNCTION_PARAMS => "PARSER_EVENT_FUNCTION_PARAMS",
PARSER_EVENT_SINGLEQUOTE => "PARSER_EVENT_SINGLEQUOTE",
PARSER_EVENT_VAR => "PARSER_EVENT_VAR",
PARSER_EVENT_LOGICBLOCK => "PARSER_EVENT_LOGICBLOCK",
PARSER_EVENT_OUTPHP => "PARSER_EVENT_OUTPHP",
PARSER_EVENT_DOCKEYWORD => "PARSER_EVENT_DOCKEYWORD",
PARSER_EVENT_DOCKEYWORD_EMAIL => "PARSER_EVENT_DOCKEYWORD_EMAIL",
PARSER_EVENT_ARRAY => "PARSER_EVENT_ARRAY",
PARSER_EVENT_INLINE_DOCKEYWORD => "PARSER_EVENT_INLINE_DOCKEYWORD",
PARSER_EVENT_EOFQUOTE => "PARSER_EVENT_EOFQUOTE",
PARSER_EVENT_INCLUDE => "PARSER_EVENT_INCLUDE",
PARSER_EVENT_INCLUDE_PARAMS => "PARSER_EVENT_INCLUDE_PARAMS",
PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS => "PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS",
PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS => "PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS",
PARSER_EVENT_DEFINE_GLOBAL => "PARSER_EVENT_DEFINE_GLOBAL",
PARSER_EVENT_GLOBAL_VALUE => "PARSER_EVENT_GLOBAL_VALUE",
PARSER_EVENT_FUNC_GLOBAL => "PARSER_EVENT_FUNC_GLOBAL",
PARSER_EVENT_STATIC_VAR => "PARSER_EVENT_STATIC_VAR",
PARSER_EVENT_DOCBLOCK_TEMPLATE => "PARSER_EVENT_DOCBLOCK_TEMPLATE",
PARSER_EVENT_END_DOCBLOCK_TEMPLATE => "PARSER_EVENT_END_DOCBLOCK_TEMPLATE",
PARSER_EVENT_METHOD_LOGICBLOCK => 'PARSER_EVENT_METHOD_LOGICBLOCK',
PARSER_EVENT_CLASS_MEMBER => 'PARSER_EVENT_CLASS_MEMBER',
PARSER_EVENT_METHOD => 'PARSER_EVENT_METHOD',
PARSER_EVENT_QUOTE_VAR => 'PARSER_EVENT_QUOTE_VAR',
PARSER_EVENT_ACCESS_MODIFIER => 'PARSER_EVENT_ACCESS_MODIFIER',
PARSER_EVENT_IMPLEMENTS => 'PARSER_EVENT_IMPLEMENTS',
PARSER_EVENT_CLASS_CONSTANT => 'PARSER_EVENT_CLASS_CONSTANT',
PARSER_EVENT_VAR_ARRAY => 'PARSER_EVENT_VAR_ARRAY',
PARSER_EVENT_VAR_ARRAY_COMMENT =>'PARSER_EVENT_VAR_ARRAY_COMMENT',
);
if (isset($lookup[$value]))
return $lookup[$value];
else return $value;
}
}
/**
* Global package page parser
*
* @deprecated in favor of tutorials
* @tutorial tutorials.pkg
* @package phpDocumentor
* @subpackage Parsers
*/
class ppageParser extends Parser
{
/** @var string */
var $package = false;
/** @var string */
var $subpackage = '';
/**
* set up invariant Parser variables
*/
function ppageParser()
{
Parser::Parser();
$this->allowableInlineTags = $GLOBALS['_phpDocumentor_inline_tutorial_tags_allowed'];
$this->eventHandlers = array();
$this->eventHandlers[PARSER_EVENT_NOEVENTS] = 'defaultHandler';
$this->eventHandlers[PARSER_EVENT_INLINE_DOCKEYWORD] = 'handleInlineDocKeyword';
}
/**
* set up invariant Parser variables
*/
function setupStates()
{
$this->tokens[STATE_NOEVENTS] = array("{@","}");
$this->tokens[STATE_INLINE_DOCKEYWORD] = array("{@","}","\t"," ");
##########################
$this->pushEvent[PARSER_EVENT_NOEVENTS] =
array(
"{@" => PARSER_EVENT_INLINE_DOCKEYWORD
);
##########################
$this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORD] = array("}");
}
/**
* Parse a new file
*
* @param string $parse_data
* @param string $package
* @param int $subpackage
* @return mixed false or parsed data
*/
function parse (&$parse_data,$xml,$package = 'default',$subpackage = '',$tutorial = '',
$category='default', $path='')
{
$this->setupStates();
$this->p_vars['total'] = new parserPackagePage($package,$xml);
$this->p_vars['tutorial'] = $tutorial;
$this->_path = $path;
$this->category = $category;
$this->package = $package;
if (!isset($subpackage) || !$subpackage) $subpackage = '';
$this->subpackage = $subpackage;
if (strlen($parse_data) == 0)
{
return false;
}
// initialize variables so E_ALL error_reporting doesn't complain
$pevent = 0;
$word = 0;
$this->p_vars['event_stack'] = new EventStack;
// change this to a new ParserStringWithInlineTags, and change all $total .= blah to $total->add(blah)
// then modify phpDocumentor_IntermediateParser->Convert to convert all package pages (the package page handler in phpDocumentor_IntermediateParser should
// save them all in a variable) to perform the linking. then, remove the legacy code from handleDocBlock
// and handleClass in Render.inc, and do a loop that converts each package page, and passes it to handleEvent
// just like Converter::walk does with the other elements. The only other addition that might be good is a
// new descendant of parserElement parserPackagePage that contains the data and stuff. Hope this helps :)
$total = '';
$this->wp->setup($parse_data);
$this->p_flags['reset_quote_data'] = true;
do
{
$lpevent = $pevent;
$pevent = $this->p_vars['event_stack']->getEvent();
if ($lpevent != $pevent)
{
$this->p_vars['last_pevent'] = $lpevent;
}
if ($this->p_vars['last_pevent'] != $pevent)
{
// its a new event so the word parser needs to be reconfigured
$this->configWordParser($pevent);
}
if (!$xml)
$this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent + 100));
$this->p_vars['last_word'] = $word;
$word = $this->wp->getWord();
if (PHPDOCUMENTOR_DEBUG == true)
{
echo "LAST: |" . $this->p_vars['last_word'] . "|\n";
echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
echo $this->wp->getPos() . ": |$word|\n";
}
if (isset($this->eventHandlers[$pevent]))
{
$handle = $this->eventHandlers[$pevent];
$this->$handle($word, $pevent);
}
} while (!($word === false));
if (!$xml)
$this->PublishEvent(PHPDOCUMENTOR_EVENT_PACKAGEPAGE,$this->p_vars['total']);
else
return $this->p_vars['total']->value;
}
/**
* Handles all non-inline tags
*
* @param string token
* @param integer parser event
*/
function defaultHandler($word, $pevent)
{
if (!$this->checkEventPush( $word, $pevent))
{
if ($word) $this->p_vars['total']->add($word);
}
}
/**
* handler for INLINE_DOCKEYWORD.
* this handler recognizes {@inline tags} like link, and parses them, replacing them directly
* in the text flow with their output.
* @param string token
* @param integer parser event
*/
function handleInlineDockeyword($word, $pevent)
{
// echo $this->wp->getPos() . ": |$word|\n";
// echo "docktype: $this->p_vars['inline_dockeyword_type']\n";
if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = false;
if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data'] = '';
if (!$this->p_vars['inline_dockeyword_type'])
{
if (in_array($word,$this->allowableInlineTags))
{
$this->p_vars['inline_dockeyword_type'] = strtolower($word);
$this->p_vars['whitesp'] = $this->wp->returnWhiteSpace;
$this->wp->setWhiteSpace(true);
} else {
if ($word == '}')
$this->p_vars['total']->add('{@');
else
{
$this->p_vars['total']->add('{@'.$word);
$this->p_vars['event_stack']->popEvent();
}
$this->p_vars['inline_dockeyword_type'] = false;
$this->p_vars['inline_dockeyword_data'] = '';
}
} else
{
if ($word != "}")
{
$this->p_vars['inline_dockeyword_data'] .= $word;
}
}
if ($this->checkEventPop($word,$pevent))
{
$this->wp->setWhiteSpace($this->p_vars['whitesp']);
if ($this->p_vars['inline_dockeyword_type']=='link')
{
// support hyperlinks of any protocol
if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:') === 0))
{
// if there is more than 1 parameter, the stuff after the space is the hyperlink text
if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))
{
$i1 = strpos(trim($this->p_vars['inline_dockeyword_data']),' ') + 1;
$link = substr(trim($this->p_vars['inline_dockeyword_data']),0,$i1 - 1);
$text = substr(trim($this->p_vars['inline_dockeyword_data']),$i1);
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($link,$text);
// ''.$text.'';
}
else
{
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
// ''.$this->p_vars['inline_dockeyword_data'].'';
} else
{
$testp = explode('#',$this->p_vars['inline_dockeyword_data']);
if (count($testp) - 1) $this->p_vars['inline_dockeyword_data'] = $testp[1];
$this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
}
if ($this->p_vars['inline_dockeyword_type']=='id')
{
$this->p_vars['inline_dockeyword_data'] = new parserIdInlineTag($this->category,$this->package,$this->subpackage,$this->p_vars['tutorial'],trim($this->p_vars['inline_dockeyword_data']));
}
if ($this->p_vars['inline_dockeyword_type'] == 'tutorial')
{
$this->p_vars['inline_dockeyword_data'] = new parserTutorialInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);
}
if ($this->p_vars['inline_dockeyword_type'] == 'toc')
{
$this->p_vars['inline_dockeyword_data'] = new parserTocInlineTag();
}
if ($this->p_vars['inline_dockeyword_type'] == 'example')
{
$example =
new parserExampleInlineTag($this->p_vars['inline_dockeyword_data'], $this->_path, true);
$this->p_vars['total']->add($example->getProgramListing());
} else
{
$this->p_vars['total']->add($this->p_vars['inline_dockeyword_data']);
}
$this->p_vars['inline_dockeyword_type'] = false;
$this->p_vars['inline_dockeyword_data'] = '';
}
}
}
?>