home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / PhpDocumentor / phpDocumentor / phpDocumentorTParser.inc < prev    next >
Encoding:
Text File  |  2008-07-02  |  104.9 KB  |  2,947 lines

  1. <?php
  2. /**
  3.  * tokenizer extension-based parser for PHP code
  4.  * 
  5.  * phpDocumentor :: automatic documentation generator
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * Copyright (c) 2002-2008 Gregory Beaver
  10.  * 
  11.  * LICENSE:
  12.  * 
  13.  * This library is free software; you can redistribute it
  14.  * and/or modify it under the terms of the GNU Lesser General
  15.  * Public License as published by the Free Software Foundation;
  16.  * either version 2.1 of the License, or (at your option) any
  17.  * later version.
  18.  * 
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  * 
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @category   ToolsAndUtilities
  29.  * @package    phpDocumentor
  30.  * @subpackage Parsers
  31.  * @author     Gregory Beaver <cellog@php.net>
  32.  * @copyright  2002-2008 Gregory Beaver
  33.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  34.  * @version    CVS: $Id: phpDocumentorTParser.inc,v 1.30 2008/02/24 02:35:44 ashnazg Exp $
  35.  * @link       http://www.phpdoc.org
  36.  * @link       http://pear.php.net/PhpDocumentor
  37.  * @since      1.2
  38.  * @todo       CS cleanup - change package to PhpDocumentor
  39.  */
  40.  
  41. /**
  42.  * Tokenizer-based parser for PHP source code
  43.  *
  44.  * @category   ToolsAndUtilities
  45.  * @package    phpDocumentor
  46.  * @subpackage Parsers
  47.  * @author     Gregory Beaver <cellog@php.net>
  48.  * @copyright  2002-2008 Gregory Beaver
  49.  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
  50.  * @version    Release: 1.4.2
  51.  * @link       http://www.phpdoc.org
  52.  * @link       http://pear.php.net/PhpDocumentor
  53.  * @todo       CS cleanup - change package to PhpDocumentor
  54.  * @todo       CS cleanup - change classname to PhpDocumentor_*
  55.  */
  56. class phpDocumentorTParser extends Parser
  57. {
  58.     /**#@+
  59.      * @access private
  60.      */
  61.     /**
  62.      * @var EventStack
  63.      */
  64.     var $_event_stack;
  65.     /**
  66.      * last event triggered before the current event
  67.      * @var integer
  68.      */
  69.     var $_last_pevent;
  70.     /**
  71.      * last word parsed
  72.      * @var integer
  73.      */
  74.     var $_last_word;
  75.     /**
  76.      * full path of the currently parsed file
  77.      * @var string
  78.      */
  79.     var $_path;
  80.     /**#@-*/
  81.  
  82.     /**#@+
  83.      * Parser Variables
  84.      * @access private
  85.      */
  86.     var $_pv_class;
  87.     var $_pv_cur_class;
  88.     var $_pv_define;
  89.     var $_pv_define_name;
  90.     var $_pv_define_value;
  91.     var $_pv_define_params_data;
  92.     var $_pv_dtype;
  93.     var $_pv_docblock;
  94.     var $_pv_dtemplate;
  95.     var $_pv_func;
  96.     var $_pv_func_param;
  97.     var $_pv_findglobal;
  98.     var $_pv_global_name;
  99.     var $_pv_global_val;
  100.     var $_pv_globals;
  101.     var $_pv_global_count;
  102.     var $_pv_include_params_data;
  103.     var $_pv_include_name;
  104.     var $_pv_include_value;
  105.     var $_pv_linenum;
  106.     var $_pv_periodline;
  107.     var $_pv_paren_count = 0;
  108.     var $_pv_statics;
  109.     var $_pv_static_count;
  110.     var $_pv_static_val;
  111.     var $_pv_quote_data;
  112.     var $_pv_function_data;
  113.     var $_pv_var;
  114.     var $_pv_varname;
  115.     var $_pv_var_value;
  116.     /**#@-*/
  117.  
  118.     /**#@+
  119.      * Parser Flags
  120.      * @access private
  121.      */
  122.     var $_pf_definename_isset = false;
  123.     var $_pf_includename_isset = false;
  124.     var $_pf_get_source = false;
  125.     var $_pf_getting_source = false;
  126.     var $_pf_internal = false;
  127.     var $_pf_in_class = false;
  128.     var $_pf_in_define = false;
  129.     var $_pf_in_global = false;
  130.     var $_pf_in_include = false;
  131.     var $_pf_in_include_value = false;
  132.     var $_pf_in_var = false;
  133.     var $_pf_interface = false;
  134.     var $_pf_funcparam_val = false;
  135.     var $_pf_quote_active = false;
  136.     var $_pf_reset_quote_data = true;
  137.     var $_pf_useperiod = false;
  138.     var $_pf_set_var_value = false;
  139.     var $_pf_var_equals = false;
  140.     /**#@-*/
  141.  
  142.     /**
  143.      * relative path of the parsed file from the base parse directory
  144.      * @var string
  145.      */
  146.     var $source_location;
  147.     var $eventHandlers = array(
  148.         PARSER_EVENT_ARRAY                      => 'handleArray',
  149.         PARSER_EVENT_VAR_ARRAY                  => 'handleArray',
  150.         PARSER_EVENT_VAR_ARRAY_COMMENT          => 'handleVarArrayComment',
  151.         PARSER_EVENT_CLASS                      => 'handleClass',
  152.         PARSER_EVENT_COMMENT                    => 'handleComment',
  153.         PARSER_EVENT_DOCBLOCK_TEMPLATE          => 'handleDocBlockTemplate',
  154.         PARSER_EVENT_END_DOCBLOCK_TEMPLATE      => 'handleEndDocBlockTemplate',
  155.         PARSER_EVENT_LOGICBLOCK                 => 'handleLogicBlock',
  156.         PARSER_EVENT_NOEVENTS                   => 'defaultHandler',
  157.         PARSER_EVENT_OUTPHP                     => 'defaultHandler',
  158.         PARSER_EVENT_DEFINE                     => 'handleDefine',
  159.         PARSER_EVENT_DEFINE_PARAMS              => 'handleDefineParams',
  160.         PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS  => 'handleDefineParamsParenthesis',
  161.         PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS => 'handleIncludeParamsParenthesis',
  162.         PARSER_EVENT_DOCBLOCK                   => 'handleDocBlock',
  163.         PARSER_EVENT_TAGS                       => 'handleTags',
  164.         PARSER_EVENT_DESC                       => 'handleDesc',
  165.         PARSER_EVENT_DOCKEYWORD                 => 'handleTag',
  166.         PARSER_EVENT_DOCKEYWORD_EMAIL           => 'handleDockeywordEmail',
  167.         PARSER_EVENT_EOFQUOTE                   => 'handleHereDoc',
  168.         PARSER_EVENT_FUNCTION                   => 'handleFunction',
  169.         PARSER_EVENT_FUNCTION_PARAMS            => 'handleFunctionParams',
  170.         PARSER_EVENT_FUNCTION_PARAM_VAR         => 'handleFunctionParams',
  171.         PARSER_EVENT_FUNC_GLOBAL                => 'handleFuncGlobal',
  172.         PARSER_EVENT_DEFINE_GLOBAL              => 'handleGlobal',
  173.         PARSER_EVENT_GLOBAL_VALUE               => 'handleGlobalValue',
  174.         PARSER_EVENT_INLINE_DOCKEYWORD          => 'handleInlineDockeyword',
  175.         PARSER_EVENT_INCLUDE                    => 'handleInclude',
  176.         PARSER_EVENT_INCLUDE_PARAMS             => 'handleIncludeParams',
  177.         PARSER_EVENT_QUOTE                      => 'handleQuote',
  178.         PARSER_EVENT_PHPCODE                    => 'handlePhpCode',
  179.         PARSER_EVENT_SINGLEQUOTE                => 'handleSingleQuote',
  180.         PARSER_EVENT_STATIC_VAR                 => 'handleStaticVar',
  181.         PARSER_EVENT_STATIC_VAR_VALUE           => 'handleStaticValue',
  182.         PARSER_EVENT_VAR                        => 'handleVar',
  183.         PARSER_EVENT_ACCESS_MODIFIER            => 'handleAccessModifier',
  184.         PARSER_EVENT_IMPLEMENTS                 => 'handleImplements',
  185.         PARSER_EVENT_CLASS_CONSTANT             => 'handleClassConstant',
  186.     );
  187.     
  188.     var $inlineTagHandlers = array(
  189.         '*'    => 'handleDefaultInlineTag',
  190.         'link' => 'handleLinkInlineTag',
  191.     );
  192.     
  193.     /**
  194.      * Constructor
  195.      *
  196.      */
  197.     function phpDocumentorTParser()
  198.     {
  199.         $this->allowableTags
  200.             = $GLOBALS['_phpDocumentor_tags_allowed'];
  201.         $this->allowableInlineTags
  202.             = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
  203.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWLINENUM,
  204.             $GLOBALS['phpDocumentor_errors']);
  205.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWFILE,
  206.             $GLOBALS['phpDocumentor_errors']);
  207.         $this->tagHandlers['author']     = 'authorTagHandler';
  208.         $this->tagHandlers['filesource'] = 'filesourceTagHandler';
  209.         $this->setupEventStates();
  210.     }
  211.     
  212.     /**
  213.      * Parse a new file
  214.      *
  215.      * @param string &$parse_data the parse data
  216.      * @param string $path        the path
  217.      * @param int    $base        number of directories to drop off the bottom 
  218.      *                            when creating names using path
  219.      * @param bool   $packages    ???
  220.      *
  221.      * @staticvar int used for recursion limiting 
  222.      *                if a handler for an event is not found
  223.      * @return bool
  224.      */
  225.     function parse (&$parse_data, $path, $base = 0, $packages = false)
  226.     {
  227.         global $_phpDocumentor_options;
  228.         static $endrecur = 0;
  229.  
  230.         $this->setupStates();
  231.         if (strlen($parse_data) == 0) {
  232.             return false;
  233.         }
  234.  
  235.         $this->configWordParser($parse_data);
  236.         // initialize variables so E_ALL error_reporting doesn't complain
  237.         $pevent = 0;
  238.         $word   = 0;
  239.  
  240.         $page = new ParserPage;
  241.         $page->setSource($this->_wp->getFileSource());
  242.         $page->setPath($path);
  243.         $this->_path = $path;
  244.         $page->setPackageOutput($packages);
  245.         $page->setFile(basename($path));
  246.         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWFILE, basename($path));
  247.         //$name = str_replace("/","_",dirname($path)) . "_" 
  248.         //    . array_shift(explode(".",$page->getFile()));
  249.         // fc@fc.clever-soft.com 11/29/2001
  250.         $name = str_replace(':', '', dirname($path)
  251.             . PATH_DELIMITER . $page->getFile());
  252.         $tmp  = explode(PATH_DELIMITER, $name);
  253.         $name = implode("---", array_slice($tmp, $base));
  254.         // if base is '', drive letter is present in windows
  255.  
  256.         $page->setName($name);
  257.         $temploc = $_phpDocumentor_options['Program_Root'] 
  258.             . PATH_DELIMITER . implode(PATH_DELIMITER,
  259.             array_slice(explode(PATH_DELIMITER, $path), $base));
  260.         
  261.         if ($temploc == $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER) {
  262.             $temploc .= $path;
  263.         }
  264.         
  265.         $this->source_location = $source_location = $temploc;
  266.         $page->setSourceLocation($source_location);
  267.  
  268.         $this->publishEvent(PHPDOCUMENTOR_EVENT_PAGE, $page);
  269.         unset($page);
  270.         do {
  271.             $lpevent = $pevent;
  272.             $pevent  = $this->_event_stack->getEvent();
  273.             if ($lpevent != $pevent) {
  274.                 $this->_last_pevent = $lpevent;
  275.             }
  276.  
  277.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE, ($pevent + 100));
  278.  
  279.             $this->_pv_last_word = $word;
  280.  
  281.             $word = $this->_wp->getWord();
  282.             if (isset($this->_pv_findglobal) && $word == $this->_pv_findglobal) {
  283.                 $this->_last_pevent = $pevent;
  284.  
  285.                 $this->_event_stack->pushEvent($pevent = PARSER_EVENT_DEFINE_GLOBAL);
  286.             }
  287.             // in wordparser, have to keep track of lines
  288.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM, $this->_wp->linenum);
  289.             if ($this->_pf_get_source) {
  290.                 if ($word[0] == T_FUNCTION) {
  291.                     $this->_wp->retrievesource($word);
  292.                     $this->_pf_get_source     = false;
  293.                     $this->_pf_getting_source = true;
  294.                 }
  295.             }
  296.  
  297.             if (PHPDOCUMENTOR_DEBUG == true) {
  298.                 echo "LAST: ";
  299.                 if (is_array($this->_pv_last_word)) {
  300.                     echo token_name($this->_pv_last_word[0]) . ' => |' 
  301.                         . htmlspecialchars($this->_pv_last_word[1]);
  302.                 } else {
  303.                     echo "|" . $this->_pv_last_word;
  304.                 }
  305.                 echo "|\n";
  306.                 echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
  307.                 echo "LASTPEVENT: "
  308.                     . $this->getParserEventName($this->_last_pevent) . "\n";
  309.                 echo $this->_wp->getPos() . ": ";
  310.                 if (is_array($word)) {
  311.                     echo token_name($word[0]) . ' => |'
  312.                         . htmlspecialchars($word[1]);
  313.                 } else {
  314.                     echo '|' . htmlspecialchars($word);
  315.                 }
  316.                 echo "|\n-------------------\n\n\n";
  317.             }
  318.  
  319.             // $this->_pf_getting_source && 
  320.             // ($pevent == PARSER_EVENT_DOCBLOCK) || 
  321.             // ($pevent == PARSER_EVENT_NOEVENTS))
  322.             if (0) {
  323.                 addError(PDERROR_SOURCE_TAG_FUNCTION_NOT_FOUND);
  324.                 // throw away source
  325.                 $this->_wp->getSource();
  326.             }
  327.             if (isset($this->eventHandlers[$pevent])) {
  328.                 $handle = $this->eventHandlers[$pevent];
  329.                 $this->$handle($word, $pevent);
  330.             } else {
  331.                 debug('WARNING: possible error, no handler for event number '
  332.                     . $pevent);
  333.                 if ($endrecur++ == 25) {
  334.                     die("FATAL ERROR, recursion limit reached");
  335.                 }
  336.             }
  337.         } while (!($word === false));
  338.         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,
  339.             PHPDOCUMENTOR_EVENT_END_PAGE);
  340.     }
  341.  
  342.     /**#@+
  343.      * @param string $word   the string word
  344.      * @param int    $pevent the token constant
  345.      * @access private
  346.      * @return void
  347.      */
  348.  
  349.     /**
  350.      * handler for COMMENT
  351.      */
  352.     function handleComment($word, $pevent)
  353.     {
  354.         $this->_wp->backupPos();
  355.         $this->_event_stack->popEvent();
  356.     }
  357.  
  358.     /**
  359.      * handler for PHPCODE.
  360.      *
  361.      * this handler recognizes the <code><?</code> php processor directive,
  362.      * and begins parsing php code
  363.      */
  364.     function handlePhpCode($word, $pevent)
  365.     {
  366.         $e = $this->checkEventPush($word, $pevent);
  367.         if (isset($this->_pv_findglobal) && $e) {
  368.             if ($e != PARSER_EVENT_DEFINE_GLOBAL
  369.                 && $e != PARSER_EVENT_ARRAY
  370.                 && $e != PARSER_EVENT_QUOTE
  371.                 && $e != PARSER_EVENT_SINGLEQUOTE
  372.                 && $e != PARSER_EVENT_COMMENT
  373.                 && $e != PARSER_EVENT_COMMENTBLOCK
  374.             ) {
  375.                 addError(PDERROR_GLOBAL_NOT_FOUND, $this->_pv_findglobal);
  376.                 $this->_wp->findGlobal(false);
  377.                 unset($this->_pv_findglobal);
  378.             }
  379.         }
  380.     }
  381.     
  382.     /**
  383.      * handler for FUNC_GLOBAL.
  384.      *
  385.      * this handler recognizes "global $var1, $var2" declarations in a function,
  386.      * and parses them
  387.      */
  388.     function handleFuncGlobal($word, $pevent)
  389.     {
  390.         if ($this->checkEventPop($word, $pevent)) {
  391.             return;
  392.         }
  393.         if (!$this->checkEventPush($word, $pevent)) {
  394.             if ($word == ',') {
  395.                 // another variable
  396.                 $this->_pv_global_count++;
  397.             } else {
  398.                 if (!isset($this->_pv_globals[$this->_pv_global_count])) {
  399.                     $this->_pv_globals[$this->_pv_global_count] = '';
  400.                 }
  401.  
  402.                 // if (!empty($this->_pv_globals[$this->_pv_global_count])) {
  403.                 //     $this->_pv_global_count++;
  404.                 // }
  405.  
  406.                 if (is_array($word)) {
  407.                     $word = $word[1];
  408.                 }
  409.                 $this->_pv_globals[$this->_pv_global_count] .= $word;
  410.             }
  411.         }
  412.     }
  413.  
  414.     /**
  415.      * handler for DEFINE_GLOBAL
  416.      */
  417.     function handleGlobal($word, $pevent)
  418.     {
  419.         if (isset($this->_pv_findglobal)) {
  420.             $this->_pv_global_name = $this->_pv_findglobal;
  421.             unset($this->_pv_findglobal);
  422.         }
  423.         if (!$this->_pf_in_global) {
  424.             $this->_pv_linenum = $this->_wp->linenum + 1;
  425.         }
  426.         $this->_pf_in_global = true;
  427.         if ($this->checkEventPush($word, $pevent)) {
  428.             $this->_wp->setWhitespace(true);
  429.         }
  430.         if ($this->checkEventPop($word, $pevent)) {
  431.             $this->_pf_in_global = false;
  432.             $a                   = new parserGlobal;
  433.             $a->setDataType($this->_pv_global_type);
  434.             $this->_pv_global_type = '';
  435.             $a->setLineNumber($this->_pv_linenum);
  436.             $a->setName($this->_pv_global_name);
  437.             if (isset($this->_pv_global_val)) {
  438.                 $a->setValue(trim($this->_pv_global_val));
  439.             }
  440.             $this->publishEvent(PHPDOCUMENTOR_EVENT_GLOBAL, $a);
  441.             unset($this->_pv_global_val);
  442.             unset($this->_pv_global_type);
  443.         }
  444.     }
  445.  
  446.     /**
  447.      * handler for GLOBAL_VALUE
  448.      */
  449.     function handleGlobalValue($word, $pevent)
  450.     {
  451.         if ($this->checkEventPush($word, $pevent)) {
  452.             return;
  453.         }
  454.         $this->_wp->setWhitespace(true);
  455.         if (!isset($this->_pv_global_val)) {
  456.             $this->_pv_global_val = '';
  457.         }
  458.         if ($this->_last_pevent == PARSER_EVENT_ARRAY) {
  459.             $this->_pv_global_val   .= $this->_pv_function_data;
  460.             $this->_pv_function_data = '';
  461.         }
  462.         if ($this->_last_pevent == PARSER_EVENT_QUOTE ||
  463.             $this->_last_pevent == PARSER_EVENT_EOFQUOTE
  464.         ) {
  465.             $this->_pv_global_val .= $this->_pv_quote_data;
  466.             unset($this->_pv_quote_data);
  467.         }
  468.         if ($this->checkEventPop($word, $pevent)) {
  469.             $this->_wp->setWhitespace(false);
  470.             $this->_wp->backupPos();
  471.             return;
  472.         }
  473.         if (is_array($word)) {
  474.             $word = $word[1];
  475.         }
  476.         $this->_pv_global_val .= $word;
  477.     }
  478.     
  479.     /**
  480.      * handler for STATIC_VAR.
  481.      *
  482.      * this handler recognizes "static $var1, 
  483.      * $var2 = 6" declarations in a function, 
  484.      * and parses them
  485.      */
  486.     function handleStaticVar($word, $pevent)
  487.     {
  488.         if ($this->checkEventPop($word, $pevent)) {
  489.             $this->_pv_static_count++;
  490.             return;
  491.         }
  492.         if (!$this->checkEventPush($word, $pevent)) {
  493.             if ($word == ',') {
  494.                 $this->_pv_static_count++;
  495.                 return;
  496.             }
  497.             if (!isset($this->_pv_statics[$this->_pv_static_count])) {
  498.                 $this->_pv_statics[$this->_pv_static_count] = '';
  499.             }
  500.             if (!empty($this->_pv_statics[$this->_pv_static_count])) {
  501.                 $this->_pv_static_count++;
  502.             }
  503.             if (is_array($word)) {
  504.                 $word = $word[1];
  505.             }
  506.             $this->_pv_statics[$this->_pv_static_count] = $word;
  507.         }
  508.     }
  509.     
  510.     /**
  511.      * handler for STATIC_VAR_VALUE.
  512.      *
  513.      * this handler parses the 6 in "static $var1, $var2 = 6"
  514.      */
  515.     function handleStaticValue($word, $pevent)
  516.     {
  517.         if ($this->checkEventPush($word, $pevent)) {
  518.             return;
  519.         }
  520.         if (!isset($this->_pv_static_val[$this->_pv_static_count])) {
  521.             $this->_pv_static_val[$this->_pv_static_count] = '';
  522.         }
  523.         if ($this->_last_pevent == PARSER_EVENT_QUOTE) {
  524.             $this->_pv_static_val[$this->_pv_static_count]
  525.                 .= $this->_pv_quote_data;
  526.             unset($this->_pv_quote_data);
  527.         }
  528.         if ($this->_last_pevent == PARSER_EVENT_ARRAY) {
  529.             $this->_pv_static_val[$this->_pv_static_count]
  530.                 .= $this->_pv_function_data;
  531.             $this->_pv_function_data = '';
  532.         }
  533.         if ($this->checkEventPop($word, $pevent)) {
  534.             $this->_pv_static_val[$this->_pv_static_count]
  535.                 = trim($this->_pv_static_val[$this->_pv_static_count]);
  536.             $this->_wp->backupPos($word);
  537.             return;
  538.         } else {
  539.             if (is_array($word)) $word = $word[1];
  540.             $this->_pv_static_val[$this->_pv_static_count] .= $word;
  541.         }
  542.     }
  543.     
  544.     /**
  545.      * handler for LOGICBLOCK
  546.      *
  547.      * Logic Blocks are the stuff between { and } in a function/method.  A
  548.      * logic block can clearly contain other logic blocks, as in:
  549.      *
  550.      * <code>
  551.      * function test($a)
  552.      * {
  553.      *    if (testcondition)
  554.      *    { // nested logic block
  555.      *    }
  556.      * }
  557.      * </code>
  558.      *
  559.      * So, the exit portion of the logic block handler must check to see if the
  560.      * logic block being exited is the top-level, and it does this by retrieving
  561.      * the last event from the stack.  If it is a function (and not a logic block)
  562.      * then it backs up the word parser so that the function will exit properly.
  563.      *
  564.      * {@source 11}
  565.      */
  566.     function handleLogicBlock($word, $pevent)
  567.     {
  568.         $a = $this->checkEventPush($word, $pevent);
  569.         if ($this->checkEventPop($word, $pevent)) {
  570.             $e = $this->_event_stack->popEvent();
  571.             $this->_event_stack->pushEvent($e);
  572.             if ($e == PARSER_EVENT_FUNCTION) {
  573.                 $this->_wp->backupPos(); 
  574.             }
  575.         }
  576.     }
  577.     
  578.     /**
  579.      * handler for FUNCTION.
  580.      *
  581.      * this handler recognizes function declarations, and parses them.  The body
  582.      * of the function is parsed by handleLogicBlock()
  583.      *
  584.      * @see handleLogicBlock()
  585.      */
  586.     function handleFunction($word, $pevent)
  587.     {
  588.         if ($e = $this->checkEventPush($word, $pevent)) {
  589.             $this->_pv_function_data = '';
  590.             if ($e == PARSER_EVENT_FUNCTION_PARAMS && !is_object($this->_pv_func)
  591.             ) {
  592.                 addErrorDie(PDERROR_FUNCTION_HAS_NONAME);
  593.             }
  594.             if ($e == PARSER_EVENT_COMMENT || $e == PARSER_EVENT_COMMENTBLOCK || 
  595.                 $e == PARSER_EVENT_FUNCTION_PARAMS || $e == PARSER_EVENT_LOGICBLOCK
  596.             ) {
  597.                 return;
  598.             }
  599.         }
  600.     
  601.         if (!isset($this->_pv_func)) {
  602.             $this->_pv_func = false;
  603.         }
  604.         if (! is_object($this->_pv_func)) {
  605.             $this->_pv_globals      = array();
  606.             $this->_pv_global_count = $this->_pv_static_count = 0;
  607.             if ($this->_pf_in_class) {
  608.                 $this->_pv_func = new parserMethod($this->_pv_cur_class); 
  609.             } else {
  610.                 $this->_pv_func = new parserFunction;
  611.                 unset($this->_accessModifiers);
  612.             }
  613.             if (isset($this->_accessModifiers)) {
  614.                 $this->_pv_func->setModifiers($this->_accessModifiers);
  615.                 unset($this->_accessModifiers);
  616.             }
  617.             $this->_pv_func->setLineNumber($this->_wp->linenum + 1);
  618.             if (is_string($word) && $word == '&') {
  619.                 $this->_pv_func->setReturnsReference();
  620.             }
  621.             if (is_array($word) && $word[0] == T_STRING) {
  622.                 $this->_pv_func->setName($word[1]);
  623.             }
  624.         } else {
  625.             if ($this->_pv_func->getReturnsReference()) {
  626.                 if (is_array($word) && $word[0] == T_STRING) {
  627.                     $this->_pv_func->setName($word[1]);
  628.                 }
  629.             }
  630.         }
  631.         if ($this->checkEventPop($word, $pevent)) {
  632.             $this->_pv_func->setEndLineNumber($this->_wp->linenum + 1);
  633.             $this->_pv_func->addGlobals($this->_pv_globals);
  634.             $this->_pv_func->addStatics($this->_pv_statics, $this->_pv_static_val);
  635.             $this->_pv_globals      = array();
  636.             $this->_pv_global_count = 0;
  637.             if ($this->_pf_getting_source) {
  638.                 $x = $this->_wp->getSource();
  639.                 $this->_pv_func->addSource($x);
  640.                 $this->_pf_get_source     = false;
  641.                 $this->_pf_getting_source = false;
  642.             }
  643.             $this->publishEvent(PHPDOCUMENTOR_EVENT_FUNCTION, $this->_pv_func); 
  644.             $this->_pv_func = false; 
  645.  
  646.             // subtle bug fixed by this, sometimes string from function body
  647.             unset($this->_pv_quote_data); // was picked up by the next function 
  648.                                           // as a default value for a parameter!
  649.         } 
  650.     }
  651.  
  652.     /**
  653.      * handler for FUNCTION_PARAMS.
  654.      *
  655.      * this handler recognizes the parameters of a function within parentheses 
  656.      * like function(param, param = default_value) and parses them
  657.      *
  658.      * @see endFunctionParam()
  659.      */
  660.     function handleFunctionParams($word, $pevent)
  661.     {
  662.         //echo $this->_wp->getPos() . ": word=|$word|\t\t\tlastword=|"
  663.         //    . $this->_pv_last_word."|\n";
  664.         //echo "function_param = '".$this->_pv_function_param."'\n";
  665.         //echo "function_data = '".$this->_pv_function_data."'\n";
  666.         $e1 = $this->checkEventPush($word, $pevent); 
  667.  
  668.         if (!$e1) {
  669.             if (($pop = $this->checkEventPop($word, $pevent)) && 
  670.                 $pevent == PARSER_EVENT_FUNCTION_PARAM_VAR
  671.             ) {
  672.                 // end of [typehint ]$param[= defaultval]
  673.                 if (is_string($word) && $word == ')') {
  674.                     $this->_wp->backupPos();
  675.                 }
  676.                 $this->endFunctionParam($word);
  677.             } elseif ($word == '=') {
  678.                 // about to parse the default value
  679.                 $this->_pf_funcparam_val = true;
  680.             } else {
  681.                 if ($this->_pf_funcparam_val) {
  682.                     // parsing default value
  683.                     if (isset($this->_pv_quote_data)) {
  684.                         $this->_pv_function_data .= $this->_pv_quote_data;
  685.                         unset($this->_pv_quote_data);
  686.                     }
  687.                     if (is_array($word)) {
  688.                         $word = $word[1];
  689.                     }
  690.                     $this->_pv_function_data .= $word;
  691.                 } else {
  692.                     // pre-param
  693.                     if ($pop) {
  694.                         return;
  695.                     }
  696.                     if (!isset($this->_pv_function_param)) {
  697.                         $this->_pv_function_param = '';
  698.                     }
  699.                     if (is_array($word) && $pevent == PARSER_EVENT_FUNCTION_PARAMS
  700.                     ) {
  701.                         if ($word[0] == T_STRING || $word[0] == T_ARRAY) {
  702.                             // object or array type hint
  703.                             $this->_pv_function_param_type = $word[1];
  704.                             return;
  705.                         }
  706.                         $word = $word[1];
  707.                     }
  708.                     $this->_pv_function_param .= $word;
  709.                 }
  710.             }
  711.         } elseif ($e1 == PARSER_EVENT_ARRAY) {
  712.             $this->_wp->setWhiteSpace(true);
  713.         } elseif ($e1 == PARSER_EVENT_FUNCTION_PARAM_VAR) {
  714.             if (!isset($this->_pv_function_param)) {
  715.                 $this->_pv_function_param = '';
  716.             }
  717.             // we just got the $var part of the param
  718.             $this->_pv_function_param .= $word[1];
  719.         }
  720.     }
  721.  
  722.     /**
  723.      * handler for ARRAY.
  724.      *
  725.      * this event handler parses arrays in default values of function
  726.      * and var definitions
  727.      */
  728.     function handleArray($word, $pevent)
  729.     {
  730.         $e = $this->checkEventPush($word, $pevent);
  731.         if ($e) {
  732.             return;
  733.         }
  734.  
  735.         if (!isset($this->_pv_function_data) || 
  736.             (isset($this->_pv_function_data) && empty($this->_pv_function_data))
  737.         ) {
  738.             $this->_pv_function_data = "array";
  739.         }
  740.  
  741.         if ($word == '(' && $this->_pv_paren_count++) {
  742.             // need extra parentheses help
  743.             $this->_event_stack->pushEvent($pevent);
  744.         }
  745.         if (is_array($word)) {
  746.             $this->_pv_function_data .= $word[1];
  747.         } else {
  748.             $this->_pv_function_data .= $word;
  749.         }
  750.         //echo "function_data = |$this->_pv_function_data|\n";
  751.  
  752.         if ($this->checkEventPop($word, $pevent)) {
  753.             $this->_pv_paren_count--;
  754.             $this->_wp->setWhiteSpace(false);
  755.         }
  756.     }
  757.     
  758.     /**
  759.      * handler for HEREDOC in a function logic block.
  760.      *
  761.      * this handler recognizes function declarations, and parses them.  The body
  762.      * of the function is parsed by handleLogicBlock()
  763.      *
  764.      * @see handleLogicBlock()
  765.      */
  766.     function handleHereDoc($word, $pevent)
  767.     {
  768.         if (is_array($this->_pv_last_word) && 
  769.             $this->_pv_last_word[0] == T_START_HEREDOC
  770.         ) {
  771.             $save = $word;
  772.             if (is_array($word)) {
  773.                 $word = $word[1];
  774.             }
  775.             $this->_pv_quote_data   = $this->_pv_last_word[1] . $word;
  776.             $this->_pf_quote_active = true;
  777.         } elseif (!$this->_pf_quote_active) {
  778.             $this->_pv_quote_data = $this->_pv_last_word[1];
  779.             $this->_event_stack->popEvent();
  780.             $this->_wp->backupPos();
  781.             return;
  782.         }
  783.         $save = $word;
  784.         if (is_array($word)) {
  785.             $word = $word[1];
  786.         }
  787.         $this->_pv_quote_data .= $word;
  788.         if ($this->checkEventPop($save, $pevent)) {
  789.             $this->_pf_quote_active = false;
  790.         }
  791.     }
  792.  
  793.     /**
  794.      * handler for QUOTE.
  795.      *
  796.      * this handler recognizes strings defined with double quotation marks (")
  797.      * and single quotation marks and handles them correctly
  798.      * in any place that they legally appear in php code
  799.      */
  800.     function handleQuote($word, $pevent)
  801.     {
  802.         if ($this->_pv_last_word == '"' || $this->_pv_last_word == "'" && 
  803.             $this->_last_pevent != PARSER_EVENT_QUOTE
  804.         ) {
  805.             $save = $word;
  806.             if (is_array($word)) {
  807.                 $word = $word[1];
  808.             }
  809.             $this->_pv_quote_data   = $this->_pv_last_word . $word;
  810.             $this->_pf_quote_active = true;
  811.             $this->checkEventPop($save, $pevent);
  812.         } elseif (!$this->_pf_quote_active) {
  813.             $this->_pv_quote_data = $this->_pv_last_word[1];
  814.             $this->_event_stack->popEvent();
  815.             $this->_wp->backupPos();
  816.             return;
  817.         }
  818.         $save = $word;
  819.         if (is_array($word)) {
  820.             $word = $word[1];
  821.         }
  822.         $this->_pv_quote_data .= $word;
  823.         if ($this->checkEventPop($save, $pevent)) {
  824.             $this->_pf_quote_active = false;
  825.         }
  826.     }
  827.  
  828.     /**
  829.      * handler for INCLUDE.
  830.      *
  831.      * this handler recognizes include/require/include_once/include_once statements,
  832.      * and publishes the data to Render
  833.      */
  834.     function handleInclude($word, $pevent)
  835.     {
  836.         if (!$this->_pf_in_include) {
  837.             $this->_pv_linenum = $this->_wp->linenum;
  838.         }
  839.         $this->_pf_in_include = true;
  840.  
  841.         $a = $this->checkEventPush($word, $pevent);
  842.         if (!$this->_pf_includename_isset) {
  843.             $this->_pf_includename_isset = true;
  844.  
  845.             $w = $this->_pv_last_word;
  846.             if (is_array($w)) {
  847.                 $w = $w[1];
  848.             }
  849.             $this->_pv_include_name = $w;
  850.             if ($a) {
  851.                 $this->_pv_include_value = '';
  852.             } else {
  853.                 if (is_array($word)) {
  854.                     $word = $word[1];
  855.                 }
  856.                 $this->_pv_include_value = $word;
  857.             }
  858.             unset($this->_pv_quote_data);
  859.         } else {
  860.             if (!$a) {
  861.                 if (empty($this->_pv_include_params_data)) {
  862.                     if ($word != ';') {
  863.                         if (is_array($word)) $word = $word[1];
  864.                         $this->_pv_include_value .= $word;
  865.                     }
  866.                 }
  867.             } else {
  868.                 if ($this->_pf_in_include_value && $a == PARSER_EVENT_INCLUDE_PARAMS
  869.                 ) {
  870.                     /* we're already inside the include value, 
  871.                      * so an open paren does NOT mean the beginning 
  872.                      * of "include parameters"...
  873.                      * it's just a part of the include's value string...
  874.                      * but we've already pushed PARSER_EVENT_INCLUDE_PARAMS 
  875.                      * onto the stack... 
  876.                      * we need to pop it off 
  877.                      * before handleIncludeParams gets called...
  878.                      */
  879.                     $this->_event_stack->popEvent();
  880.                     // also need to keep that open parens...
  881.                     $this->_pv_include_value .= $word;
  882.                 }
  883.                 $this->_pv_include_params_data = '';
  884.             }
  885.         }
  886.  
  887.         if (!empty($this->_pv_include_value)) {
  888.             $this->_pf_in_include_value = true;
  889.         }
  890.  
  891.         if ($this->checkEventPop($word, $pevent)) {
  892.             $this->_pv_include = new parserInclude;
  893.             $this->_pv_include->setLineNumber($this->_pv_linenum + 1);
  894.             $this->_pf_in_include = false;
  895.             $this->_pv_include->setName($this->_pv_include_name);
  896.             $this->_pv_include->setValue($this->_pv_include_value);
  897.             $this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE, $this->_pv_include);
  898.             $this->_pf_includename_isset = false;
  899.             $this->_pf_in_include_value  = false;
  900.             unset($this->_pv_include);
  901.             unset($this->_pv_include_name);
  902.             unset($this->_pv_include_value);
  903.             unset($this->_pv_include_params_data);
  904.         } elseif ($this->_last_pevent == PARSER_EVENT_INCLUDE_PARAMS) {
  905.             // include is part of a larger statement
  906.             // force ending of include
  907.             $this->_event_stack->popEvent();
  908.             $this->_pv_include = new parserInclude;
  909.             $this->_pv_include->setLineNumber($this->_pv_linenum + 1);
  910.             $this->_pf_in_include = false;
  911.             $this->_pv_include->setName($this->_pv_include_name);
  912.             $this->_pv_include->setValue($this->_pv_include_value);
  913.             $this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE, $this->_pv_include);
  914.             $this->_pf_includename_isset = false;
  915.             $this->_pf_in_include_value  = false;
  916.             unset($this->_pv_include);
  917.             unset($this->_pv_include_name);
  918.             unset($this->_pv_include_value);
  919.             unset($this->_pv_include_params_data);
  920.         }
  921.     }
  922.     
  923.     /**
  924.      * handler for INCLUDE_PARAMS.
  925.      *
  926.      * this handler parses the contents of ( ) 
  927.      * in include/require/include_once/include_once statements
  928.      */
  929.     function handleIncludeParams($word, $pevent)
  930.     {
  931.         $e = $this->checkEventPush($word, $pevent);
  932.         if ($e == PARSER_EVENT_COMMENT) {
  933.             return;
  934.         }
  935.         
  936.         if (!isset($this->_pv_include_params_data)) {
  937.             $this->_pv_include_params_data = '';
  938.         }
  939.         
  940.         if ($this->checkEventPop($word, $pevent)) {
  941.             if (!empty($this->_pv_include_params_data)) {
  942.                 $this->_pv_include_value = $this->_pv_include_params_data;
  943.             } else {
  944.                 $w = $this->_pv_last_word;
  945.                 if (is_array($w)) {
  946.                     $w = $w[1];
  947.                 }
  948.                 $this->_pv_include_value = $w;
  949.             }
  950.         }
  951.         if (is_array($word)) {
  952.             $word = $word[1];
  953.         }
  954.         $this->_pv_include_params_data .= $word;
  955.     }
  956.     
  957.     /**
  958.      * handler for INCLUDE_PARAMS_PARENTHESIS.
  959.      *
  960.      * this handler takes all parenthetical statements within file in:
  961.      * include statement include(file), and handles them properly
  962.      */
  963.     function handleIncludeParamsParenthesis($word, $pevent)
  964.     {
  965.         $this->checkEventPush($word, $pevent);
  966.         $this->checkEventPop($word, $pevent);
  967.         if (is_array($word)) {
  968.             $word = $word[1];
  969.         }
  970.         $this->_pv_include_params_data .= $word;
  971.     }
  972.  
  973.     /**
  974.      * handler for DEFINE.
  975.      *
  976.      * handles define(constant, value); statements
  977.      */
  978.     function handleDefine($word, $pevent)
  979.     {
  980.         if (!$this->_pf_in_define) {
  981.             $this->_pv_linenum = $this->_wp->linenum + 1;
  982.         }
  983.         $this->_pf_in_define = true;
  984.         $this->checkEventPush($word, $pevent);
  985.  
  986.         $this->_pf_definename_isset   = false;
  987.         $this->_pv_define_params_data = '';
  988.         unset($this->_pv_quote_data);
  989.         if ($this->checkEventPop($word, $pevent)) {
  990.             $this->_pf_in_define = false;
  991.             $this->_pv_define    = new parserDefine;
  992.             $this->_pv_define->setLineNumber($this->_pv_linenum);
  993.             $this->_pv_define->setName($this->_pv_define_name);
  994.             $this->_pv_define->setValue($this->_pv_define_value);
  995.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DEFINE, $this->_pv_define);
  996.             $this->_pf_definename_isset = false;
  997.             unset($this->_pv_define);
  998.             unset($this->_pv_define_name);
  999.             unset($this->_pv_define_value);
  1000.             $this->_pf_in_define          = false;
  1001.             $this->_pv_define_params_data = '';
  1002.         }
  1003.     }
  1004.     
  1005.     /**
  1006.      * handler for DEFINE_PARAMS.
  1007.      *
  1008.      * handles the parsing of constant and value in define(constant, value);
  1009.      */
  1010.     function handleDefineParams($word, $pevent)
  1011.     {
  1012.         $e = $this->checkEventPush($word, $pevent);
  1013.         if ($e && $e != PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS) {
  1014.             return;
  1015.         }
  1016.         
  1017.         if (!isset($this->_pv_define_params_data)) {
  1018.             $this->_pv_define_params_data = '';
  1019.         }
  1020.         
  1021.         if ($this->checkEventPop($word, $pevent)) {
  1022.             if ($this->_last_pevent == PARSER_EVENT_QUOTE ||
  1023.                 $this->_last_pevent == PARSER_EVENT_EOFQUOTE
  1024.             ) {
  1025.                 $this->_pv_define_params_data .= $this->_pv_quote_data;
  1026.                 unset($this->_pv_quote_data);
  1027.             }
  1028.             if (is_array($word)) {
  1029.                 $word = $word[1];
  1030.             }
  1031.             if (!empty($this->_pv_define_params_data)) {
  1032.                 //echo $this->_pv_define_params_data."\n";
  1033.                 $this->_pv_define_value = $this->_pv_define_params_data;
  1034.             } else {
  1035.                 $w = $this->_pv_last_word;
  1036.                 if (is_array($this->_pv_last_word)) {
  1037.                     $w = $this->_pv_last_word[1];
  1038.                 }
  1039.                 if (!empty($w)) {
  1040.                     $this->_pv_define_value = $w;
  1041.                 } else {
  1042.                     $this->_pv_define_value = "";
  1043.                     switch ($w) {
  1044.                     case 0:
  1045.                         $this->_pv_define_value = "0";
  1046.                         break;
  1047.                     case null:
  1048.                         $this->_pv_define_value = "null";
  1049.                         break;
  1050.                     case "":
  1051.                         $this->_pv_define_value = "";
  1052.                         break;
  1053.                     }
  1054.                 }
  1055.             }
  1056.         }
  1057.         if ($this->_pf_definename_isset) {
  1058.             if (is_array($word)) {
  1059.                 $word = $word[1];
  1060.             }
  1061.             $this->_pv_define_params_data .= $word;
  1062.         } else {
  1063.             if ($word != ",") {
  1064.                 if (is_array($word)) {
  1065.                     $word = $word[1];
  1066.                 }
  1067.                 $this->_pv_define_params_data .= $word;
  1068.             } else {
  1069.                 if (substr($this->_pv_define_params_data, 0, 1) ==
  1070.                     substr($this->_pv_define_params_data,
  1071.                         strlen($this->_pv_define_params_data) - 1) &&
  1072.                     in_array(substr($this->_pv_define_params_data,
  1073.                         0, 1), array('"', "'"))
  1074.                 ) {
  1075.                     // remove leading and ending quotation marks 
  1076.                     // if there are only two
  1077.                     $a = substr($this->_pv_define_params_data, 0, 1);
  1078.                     $b = substr($this->_pv_define_params_data, 1, 
  1079.                         strlen($this->_pv_define_params_data) - 2);
  1080.                     if (strpos($b, $a) === false) {
  1081.                         $this->_pv_define_params_data = $b;
  1082.                     }
  1083.                 }
  1084.                 $this->_pf_definename_isset   = true;
  1085.                 $this->_pv_define_name        = $this->_pv_define_params_data;
  1086.                 $this->_pv_define_params_data = '';
  1087.             }
  1088.         }
  1089.     }
  1090.     
  1091.     /**
  1092.      * handler for DEFINE_PARAMS_PARENTHESIS.
  1093.      *
  1094.      * this handler takes all parenthetical statements within constant or value in:
  1095.      * define(constant, value) of a define statement, and handles them properly
  1096.      */
  1097.     function handleDefineParamsParenthesis($word, $pevent)
  1098.     {
  1099.         $e = $this->checkEventPush($word, $pevent);
  1100.         $this->checkEventPop($word, $pevent);
  1101.         if ($this->_last_pevent == PARSER_EVENT_QUOTE) {
  1102.             $this->_pv_define_params_data .= $this->_pv_quote_data;
  1103.             unset($this->_pv_quote_data);
  1104.         }
  1105.         if (is_array($word)) {
  1106.             $word = $word[1];
  1107.         }
  1108.         $this->_pv_define_params_data .= $word;
  1109.     }
  1110.  
  1111.     /**
  1112.      * handler for IMPLEMENTS.
  1113.      *
  1114.      * this handler parses a class statement's implements clause (PHP 5)
  1115.      */
  1116.     function handleImplements($word, $pevent)
  1117.     {
  1118.         if ($this->checkEventPop($word, $pevent)) {
  1119.             $this->_wp->backupPos();
  1120.             return;
  1121.         }
  1122.         if (is_array($word) && $word[0] == T_STRING) {
  1123.             $this->_pv_class->addImplements($word[1]);
  1124.         }
  1125.     }
  1126.  
  1127.     /**
  1128.      * handler for ACCESS_MODIFIER.
  1129.      *
  1130.      * this handler parses public/private/protected/static/abstract PHP 5 modifiers
  1131.      */
  1132.     function handleAccessModifier($word, $pevent)
  1133.     {
  1134.         if (!isset($this->_accessModifiers)) {
  1135.             $this->_accessModifiers = array();
  1136.         }
  1137.         $this->_wp->backupPos();
  1138.         $this->_event_stack->popEvent();
  1139.         if ($word[0] == T_VARIABLE) {
  1140.             // this is a PHP5-style variable with no "var"
  1141.             $this->_event_stack->pushEvent(PARSER_EVENT_VAR);
  1142.         }
  1143.         $this->_accessModifiers[] = strtolower($this->_pv_last_word[1]);
  1144.     }
  1145.  
  1146.     /**
  1147.      * handler for CLASS.
  1148.      *
  1149.      * this handler parses a class/interface statement
  1150.      */
  1151.     function handleClass($word, $pevent)
  1152.     {
  1153.         if (!$this->_pf_in_class) {
  1154.             $this->_pf_in_class = true;
  1155.             if ($this->_pv_last_word[0] == T_INTERFACE) {
  1156.                 $this->_pf_interface = true;
  1157.             } else {
  1158.                 $this->_pf_interface = false;
  1159.             }
  1160.         }
  1161.         $a = $this->checkEventPush($word, $pevent);
  1162.  
  1163.         if (!isset($this->_pv_class)) {
  1164.             $this->_pv_class = false;
  1165.         }
  1166.         if (!is_subclass_of($this->_pv_class, "parserBase")) {
  1167.             $this->_pv_class = new parserClass;
  1168.             if (isset($this->_accessModifiers)) {
  1169.                 $this->_pv_class->setModifiers($this->_accessModifiers);
  1170.                 unset($this->_accessModifiers);
  1171.             }
  1172.             if ($this->_pf_interface) {
  1173.                 $this->_pv_class->setInterface();
  1174.             }
  1175.             $this->_pv_class->setLineNumber($this->_wp->linenum + 1);
  1176.             $this->_pv_class->setname($word[1]);
  1177.             $this->_pv_cur_class = $word[1];
  1178.             $this->_pv_class->setSourceLocation($this->source_location);
  1179.         }
  1180.  
  1181.         if (is_array($this->_pv_last_word) && $this->_pv_last_word[0] == T_EXTENDS
  1182.         ) {
  1183.             // I don't know why I am so nice, this fixes 1150809
  1184.             if ($word[1] == $this->_pv_class->getName()) {
  1185.                 addErrorDie(PDERROR_CANNOT_EXTEND_SELF, $word[1]);
  1186.             }
  1187.             $this->_pv_class->setExtends($word[1]);
  1188.         }
  1189.  
  1190.         if ($word == "{") {
  1191.             $this->publishEvent(PHPDOCUMENTOR_EVENT_CLASS, $this->_pv_class);
  1192.         }
  1193.         //echo $this->wp->getPos() . ": |$word|\n";
  1194.         if ($this->checkEventPop($word, $pevent)) {
  1195.             $this->_pv_class->setEndLineNumber($this->_wp->linenum + 1);
  1196.             $this->_pf_in_class = $this->_pf_interface = false;
  1197.             // throw an event when class is done
  1198.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE, STATE_END_CLASS);
  1199.             $this->_pv_class = false;
  1200.         }
  1201.     }
  1202.     
  1203.     /**
  1204.      * handler for VAR_ARRAY_COMMENT
  1205.      *
  1206.      * if parsing a default value, add the comment to the text
  1207.      */
  1208.     function handleVarArrayComment($word, $pevent)
  1209.     {
  1210.         $this->_pv_function_data .= $this->_pv_last_word[1];
  1211.         return $this->handleComment($word, $pevent);
  1212.     }
  1213.  
  1214.     /**
  1215.      * handler for VAR.
  1216.      *
  1217.      * handle a var $varname = default_value;
  1218.      * or var $varname; statement 
  1219.      * in a class definition
  1220.      */
  1221.     function handleVar($word, $pevent)
  1222.     {
  1223.         if (!$this->_pf_in_var) {
  1224.             $this->_pf_set_var_value = false;
  1225.             $this->_pv_var_value     = '';
  1226.             $this->_pv_linenum       = $this->_wp->linenum + 1;
  1227.         }
  1228.         $this->_pf_in_var = true;
  1229.         //echo $word."\n";
  1230.         $e = $this->checkEventPush($word, $pevent);
  1231.         
  1232.         if (!isset($this->_pv_var)) {
  1233.             $this->_pv_var = false;
  1234.         }
  1235.         if ($word == '=' || $word == ';' || $word == ',') {
  1236.             $this->_wp->setWhitespace(true);
  1237.             $this->_pf_var_equals = true;
  1238.             $this->_pv_var        = new parserVar($this->_pv_cur_class);
  1239.             $this->_pv_var->setName($this->_pv_varname);
  1240.         }
  1241.         if ($this->_last_pevent == PARSER_EVENT_VAR_ARRAY) {
  1242.             if (isset($this->_pv_function_data)) {
  1243.                 $this->_pv_var->setValue($this->_pv_function_data);
  1244.             }
  1245.             $this->_pf_set_var_value = true;
  1246.             unset($this->_pv_function_data);
  1247.         } elseif ($this->_pf_var_equals && $word != ';' && 
  1248.             $word != '=' && $word != ',' && !$e
  1249.         ) {
  1250.             if (is_array($word)) {
  1251.                 $word = $word[1];
  1252.             }
  1253.             $this->_pv_var_value .= $word;
  1254.         }
  1255.         if ($word == ',') {
  1256.             if (!$this->_pf_set_var_value) {
  1257.                 $this->_pv_var->setValue($this->_pv_var_value);
  1258.             }
  1259.             $this->_pf_set_var_value = false;
  1260.             unset($this->_pv_var_value);
  1261.             $this->_pv_var->setEndLineNumber($this->_wp->linenum + 1);
  1262.             $this->_pv_var->setLineNumber($this->_pv_linenum);
  1263.             if (isset($this->_accessModifiers)) {
  1264.                 $this->_pv_var->setModifiers($this->_accessModifiers);
  1265.             }
  1266.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR, $this->_pv_var);
  1267.             unset($this->_pv_var);
  1268.             $this->_pf_in_var     = false;
  1269.             $this->_pf_var_equals = false;
  1270.             $this->_pv_varname    = '';
  1271.             return;
  1272.         }
  1273.         if ($this->checkEventPop($word, $pevent)) {
  1274.             $this->_wp->setWhitespace(false);
  1275.             if (!$this->_pf_set_var_value) {
  1276.                 $this->_pv_var->setValue($this->_pv_var_value);
  1277.             }
  1278.             $this->_pf_set_var_value = false;
  1279.             unset($this->_pv_var_value);
  1280.             $this->_pv_var->setEndLineNumber($this->_wp->linenum + 1);
  1281.             $this->_pv_var->setLineNumber($this->_pv_linenum);
  1282.             if (isset($this->_accessModifiers)) {
  1283.                 $this->_pv_var->setModifiers($this->_accessModifiers);
  1284.                 unset($this->_accessModifiers);
  1285.             }
  1286.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR, $this->_pv_var);
  1287.             unset($this->_pv_var);
  1288.             $this->_pf_in_var     = false;
  1289.             $this->_pf_var_equals = false;
  1290.             $this->_pv_varname    = '';
  1291.             return;
  1292.         }
  1293.         if ($word[0] == T_VARIABLE) {
  1294.             $this->_pv_varname = $word[1];
  1295.         }
  1296.     }
  1297.  
  1298.     /**
  1299.      * handler for CLASS_CONSTANT.
  1300.      *
  1301.      * handle a const constname = default_value; statement in a class definition
  1302.      */
  1303.     function handleClassConstant($word, $pevent)
  1304.     {
  1305.         if (!$this->_pf_in_const) {
  1306.             $this->_pf_set_const_value = false;
  1307.             $this->_pv_const_value     = '';
  1308.             $this->_pv_linenum         = $this->_wp->linenum + 1;
  1309.         }
  1310.         $this->_pf_in_const = true;
  1311.         //echo $word."\n";
  1312.         $e = $this->checkEventPush($word, $pevent);
  1313.         
  1314.         if (!isset($this->_pv_const)) {
  1315.             $this->_pv_const = false;
  1316.         }
  1317.         if ($word == '=' || $word == ';' || $word == ',') {
  1318.             $this->_wp->setWhitespace(true);
  1319.             $this->_pf_const_equals = true;
  1320.             $this->_pv_const        = new parserConst($this->_pv_cur_class);
  1321.             $this->_pv_const->setName($this->_pv_constname);
  1322.         }
  1323.         if ($this->_last_pevent == PARSER_EVENT_VAR_ARRAY) {
  1324.             if (isset($this->_pv_function_data)) {
  1325.                 $this->_pv_const->setValue($this->_pv_function_data);
  1326.             }
  1327.             $this->_pf_set_const_value = true;
  1328.             unset($this->_pv_function_data);
  1329.         } elseif ($this->_pf_const_equals && $word != ';' && 
  1330.             $word != '=' && $word != ',' && !$e
  1331.         ) {
  1332.             if (is_array($word)) {
  1333.                 $word = $word[1];
  1334.             }
  1335.             $this->_pv_const_value .= $word;
  1336.         }
  1337.         if ($word == ',') {
  1338.             if (!$this->_pf_set_const_value) {
  1339.                 $this->_pv_const->setValue($this->_pv_const_value);
  1340.             }
  1341.             $this->_pf_set_const_value = false;
  1342.             unset($this->_pv_const_value);
  1343.             $this->_pv_const->setEndLineNumber($this->_wp->linenum + 1);
  1344.             $this->_pv_const->setLineNumber($this->_pv_linenum);
  1345.             $this->publishEvent(PHPDOCUMENTOR_EVENT_CONST, $this->_pv_const);
  1346.             unset($this->_pv_const);
  1347.             $this->_pf_in_const     = false;
  1348.             $this->_pf_const_equals = false;
  1349.             $this->_pv_constname    = '';
  1350.             return;
  1351.         }
  1352.         if ($this->checkEventPop($word, $pevent)) {
  1353.             $this->_wp->setWhitespace(false);
  1354.             if (!$this->_pf_set_const_value) {
  1355.                 $this->_pv_const->setValue($this->_pv_const_value);
  1356.             }
  1357.             $this->_pf_set_const_value = false;
  1358.             unset($this->_pv_const_value);
  1359.             $this->_pv_const->setEndLineNumber($this->_wp->linenum + 1);
  1360.             $this->_pv_const->setLineNumber($this->_pv_linenum);
  1361.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR, $this->_pv_const);
  1362.             unset($this->_pv_const);
  1363.             $this->_pf_in_const     = false;
  1364.             $this->_pf_const_equals = false;
  1365.             $this->_pv_constname    = '';
  1366.             return;
  1367.         }
  1368.         if ($word[0] == T_STRING && !$this->_pf_const_equals) {
  1369.             $this->_pv_constname = $word[1];
  1370.         }
  1371.     }
  1372.     
  1373.     /**
  1374.      * Handler for the 
  1375.      * {@tutorial phpDocumentor.howto.pkg#using.command-line.javadocdesc}
  1376.      * command-line switch DocBlocks.
  1377.      *
  1378.      * @todo CS cleanup - rename to javaDoc* for camelCasing rule
  1379.      */
  1380.     function JavaDochandleDocblock($word, $pevent)
  1381.     {
  1382.         $this->commonDocBlock($word, $pevent, 'handleJavaDocDesc');
  1383.     }
  1384.     
  1385.     /**
  1386.      * Handler for normal DocBlocks
  1387.      */
  1388.     function handleDocBlock($word, $pevent)
  1389.     {
  1390.         $this->commonDocBlock($word, $pevent, 'handleDesc');
  1391.     }
  1392.     /**#@-*/
  1393.     
  1394.     /**
  1395.      * Helper function for {@link handleFunctionParams()}
  1396.      *
  1397.      * This function adds a new parameter to the parameter list
  1398.      *
  1399.      * @param string $word the parameter word
  1400.      *
  1401.      * @return void
  1402.      * @access private
  1403.      */
  1404.     function endFunctionParam($word)
  1405.     {
  1406.         if (isset($this->_pv_quote_data)) {
  1407.             $this->_pv_function_data .= $this->_pv_quote_data;
  1408.             unset($this->_pv_quote_data);
  1409.         }
  1410.         if (isset($this->_pv_function_param)) {
  1411.             $this->_pv_func->addParam($this->_pv_function_param,
  1412.                 $this->_pv_function_data,
  1413.                 $this->_pf_funcparam_val,
  1414.                 $this->_pv_function_param_type);
  1415.             unset($this->_pv_function_param);
  1416.             $this->_pv_function_data       = '';
  1417.             $this->_pf_funcparam_val       = false;
  1418.             $this->_pv_function_param_type = null;
  1419.         }
  1420.     }
  1421.  
  1422.     /**
  1423.      * Common DocBlock Handler for both JavaDoc-format and normal DocBlocks
  1424.      *
  1425.      * @param string $word        the word
  1426.      * @param int    $pevent      the parser event
  1427.      * @param string $deschandler the handler to use
  1428.      *
  1429.      * @return void
  1430.      * @access private
  1431.      */
  1432.     function commonDocBlock($word, $pevent, $deschandler)
  1433.     {
  1434.         $this->_wp->backupPos();
  1435.         $this->_event_stack->popEvent();
  1436.         $word  = $this->_pv_last_word[1];
  1437.         $dtype = '_pv_docblock';
  1438.         if (strpos($word, '/**') !== 0) {
  1439.             // not a docblock
  1440.             // $this->_wp->backupPos();
  1441.             $this->_event_stack->pushEvent(PARSER_EVENT_COMMENT);
  1442.             return;
  1443.         }
  1444.         if ($word == '/**#@-*/') {
  1445.             // stop using docblock template
  1446.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,
  1447.                 PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE);
  1448.             unset($this->_pv_dtemplate);
  1449.             return;
  1450.         }
  1451.         if (strpos($word, '/**#@+') === 0) {
  1452.             // docblock template definition
  1453.             $dtype = '_pv_dtemplate';
  1454.             // strip /**#@+ and */
  1455.             $word = substr($word, 6).'*';
  1456.             $word = trim(substr($word, 0, strlen($word) - 3));
  1457.             if (strlen($word) && $word{0} != '*') {
  1458.                 $word = "* $word";
  1459.             }
  1460.         } else {
  1461.             // strip /** and */
  1462.             $word = substr($word, 2);
  1463.             $word = substr($word, 0, strlen($word) - 2);
  1464.         }
  1465.         $lines = explode("\n", trim($word));
  1466.         $go    = count($lines);
  1467.         for ($i=0; $i < $go; $i++) {
  1468.             if (substr(trim($lines[$i]), 0, 1) != '*') {
  1469.                 unset($lines[$i]);
  1470.             } else {
  1471.                 // remove leading "* "
  1472.                 $lines[$i] = substr(trim($lines[$i]), 1);
  1473.             }
  1474.         }
  1475.         // remove empty lines
  1476.         if ($lines == array(false)) { 
  1477.             // prevent PHP 5.2 segfault (see http://bugs.php.net/bug.php?id=39350)
  1478.             $lines = array('');
  1479.         }
  1480.         $lines = explode("\n", trim(join("\n", $lines)));
  1481.         for ($i = 0; $i < count($lines); $i++) {
  1482.             if (substr(trim($lines[$i]), 0, 1) == '@' && 
  1483.                 substr(trim($lines[$i]), 0, 2) != '@ '
  1484.             ) {
  1485.                 $tagindex = $i;
  1486.                 $i        = count($lines);
  1487.             }
  1488.         }
  1489.         if (isset($tagindex)) {
  1490.             $tags = array_slice($lines, $tagindex);
  1491.             $desc = array_slice($lines, 0, $tagindex);
  1492.         } else {
  1493.             $tags = array();
  1494.             $desc = $lines;
  1495.         }
  1496.         //var_dump($desc,$tags);
  1497.         $this->$dtype = new parserDocBlock;
  1498.         $this->$dtype->setLineNumber($this->_wp->_docblock_linenum + 1);
  1499.         $this->$dtype->setEndLineNumber($this->_wp->linenum);
  1500.         $this->_pv_dtype = $dtype;
  1501.         $this->$deschandler($desc);
  1502.         $this->handleTags($tags);
  1503.         if ($dtype == '_pv_docblock') {
  1504.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK, $this->$dtype);
  1505.             $this->$dtype = new parserDocBlock();
  1506.         } else {
  1507.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE,
  1508.                 $this->$dtype);
  1509.         }
  1510.     }
  1511.     
  1512.     /**
  1513.      * Handles JavaDoc descriptions
  1514.      *
  1515.      * @param string $desc the description
  1516.      *
  1517.      * @return void
  1518.      * @access private
  1519.      */
  1520.     function handleJavaDocDesc($desc)
  1521.     {
  1522.         unset($this->_pv_periodline);
  1523.         $this->_pf_useperiod = false;
  1524.         if (empty($desc)) {
  1525.             $desc = array('');
  1526.         }
  1527.         foreach ($desc as $i => $line) {
  1528.             $line = trim($line);
  1529.             if (!isset($this->_pv_periodline) && 
  1530.                 substr($line, strlen($line) - 1) == '.'
  1531.             ) {
  1532.                 $this->_pv_periodline = $i;
  1533.                 $this->_pf_useperiod  = true;
  1534.             }
  1535.         }
  1536.         if (!isset($this->_pv_periodline)) {
  1537.             $this->_pv_periodline = 0;
  1538.         }
  1539.  
  1540.         $dtype = $this->_pv_dtype;
  1541.         if ($dtype == '_pv_docblock') {
  1542.             $save = $desc;
  1543.             // strip leading <p>
  1544.             if (strpos($desc[0], '<p>') === 0) {
  1545.                 $desc[0] = substr($desc[0], 3);
  1546.             }
  1547.             $sdesc = new parserDesc;
  1548.             $desci = '';
  1549.             for ($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++
  1550.             ) {
  1551.                 if (strpos($desc[$i], '.') !== false) {
  1552.                     $desci .= substr($desc[$i], 0, strpos($desc[$i], '.') + 1);
  1553.                 } else {
  1554.                     $desci .= $desc[$i];
  1555.                 }
  1556.                 $desci .= "\n";
  1557.             }
  1558.             $sdesc->add($this->getInlineTags($desci));
  1559.             $desc = $save;
  1560.         
  1561.             $my_desc = new parserDesc;
  1562.             if (isset($this->_pv_dtemplate)) {
  1563.                 // copy template values if not overridden
  1564.                 if (!$this->_pv_docblock->getExplicitPackage()) {
  1565.                     if ($p = $this->_pv_dtemplate->getKeyword('package')) {
  1566.                         $this->_pv_docblock->addKeyword('package', $p);
  1567.                         $this->_pv_docblock->setExplicitPackage();
  1568.                     }
  1569.                     if ($p = $this->_pv_dtemplate->getKeyword('category')) {
  1570.                         $this->_pv_docblock->addKeyword('category', $p);
  1571.                         $this->_pv_docblock->setExplicitCategory();
  1572.                     }
  1573.                     if ($p = $this->_pv_dtemplate->getKeyword('subpackage')) {
  1574.                         $this->_pv_docblock->addKeyword('subpackage', $p);
  1575.                     }
  1576.                 }
  1577.                 $tags = $this->_pv_dtemplate->listTags();
  1578.                 foreach ($tags as $tag) {
  1579.                     $this->_pv_docblock->addTag($tag);
  1580.                 }
  1581.                 if (!count($this->_pv_docblock->params)) {
  1582.                     $this->_pv_docblock->params = $this->_pv_dtemplate->params;
  1583.                 }
  1584.                 $my_desc->add($this->_pv_dtemplate->desc);
  1585.             }
  1586.             //echo "i = ".$this->_pv_periodline."; i < " . count($desc) . "\n";
  1587.             $desci = '';
  1588.             for ($i = 0; $i < count($desc); $i++) {
  1589.                 // the line will not be set if it doesn't start with a *
  1590.                 if (isset($desc[$i])) {
  1591.                     $desci .= $desc[$i] . "\n";
  1592.                 }
  1593.             }
  1594.             $my_desc->add($this->getInlineTags($desci));
  1595.         } else {
  1596.             $sdesc = new parserDesc;
  1597.             $save  = $desc;
  1598.             // strip leading <p>
  1599.             if (strpos($desc[0], '<p>') === 0) {
  1600.                 $desc[0] = substr($desc[0], 3);
  1601.             }
  1602.             $desci = '';
  1603.             for ($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++
  1604.             ) {
  1605.                 if (strpos($desc[$i], '.') !== false) {
  1606.                     $desci .= substr($desc[$i], 0, strpos($desc[$i], '.') + 1);
  1607.                 } else {
  1608.                     $desci .= $desc[$i];
  1609.                 }
  1610.                 $desci .= "\n";
  1611.             }
  1612.             $sdesc->add($this->getInlineTags($desci));
  1613.             $desc = $save;
  1614.         
  1615.             $my_desc = new parserDesc;
  1616.             $desci   = '';
  1617.             for ($i=0; $i < count($desc); $i++) {
  1618.                 if (isset($desc[$i])) {
  1619.                     $desci .= $desci[$i] . "\n";
  1620.                 }
  1621.             }
  1622.             $my_desc->add($this->getInlineTags($desci));
  1623.         }
  1624.         
  1625.         if ($this->_pf_internal) {
  1626.             addError(PDERROR_INTERNAL_NOT_CLOSED);
  1627.             $this->_pf_internal = false;
  1628.         }
  1629.         $this->$dtype->setShortDesc($sdesc);
  1630.         $this->$dtype->setDesc($my_desc);
  1631.         unset($my_desc);
  1632.         //var_dump($this->$dtype);
  1633.         //exit;
  1634.     }
  1635.     
  1636.     /**
  1637.      * Process the Long Description of a DocBlock
  1638.      *
  1639.      * @param array $desc array of lines containing the description
  1640.      *                    with leading asterisk "*" stripped off.
  1641.      *
  1642.      * @return void
  1643.      * @access private
  1644.      */
  1645.     function handleDesc($desc)
  1646.     {
  1647.         unset($this->_pv_periodline);
  1648.         $this->_pf_useperiod = false;
  1649.         foreach ($desc as $i => $line) {
  1650.             $line = trim($line);
  1651.             if (!isset($this->_pv_periodline) && 
  1652.                 substr($line, strlen($line) - 1) == '.'
  1653.             ) {
  1654.                 $this->_pv_periodline = $i;
  1655.                 $this->_pf_useperiod  = true;
  1656.             }
  1657.         }
  1658.         if (!isset($this->_pv_periodline)) {
  1659.             $this->_pv_periodline = 0;
  1660.         }
  1661.         if ($this->_pv_periodline > 3) {
  1662.             $this->_pf_useperiod = false;
  1663.         } else {
  1664.             for ($i = 0; $i < $this->_pv_periodline; $i++) {
  1665.                 if (strlen($desc[$i]) == 0 && isset($desc[$i - 1]) && 
  1666.                     strlen($desc[$i - 1])
  1667.                 ) {
  1668.                     $this->_pv_periodline = $i;
  1669.                 }
  1670.             }
  1671.         }
  1672.         for ($i=0;$i <= $this->_pv_periodline && $i < count($desc);$i++) {
  1673.             if (!strlen(trim($desc[$i]))) {
  1674.                 $this->_pf_useperiod = false;
  1675.             }
  1676.         }
  1677.         // figure out the shortdesc
  1678.         if ($this->_pf_useperiod === false) {
  1679.             // use the first non blank line for short desc
  1680.             for ($i = 0; $i < count($desc); $i++) {
  1681.                 if (strlen($desc[$i]) > 0) {
  1682.                     $this->_pv_periodline = $i;
  1683.                     $i                    = count($desc);
  1684.                 }
  1685.             }
  1686.         
  1687.             // check to see if we are going to use a blank line to end the shortdesc
  1688.             // this can only be in the first 4 lines
  1689.             if (count($desc) > 4) {
  1690.                 $max = 4;
  1691.             } else {
  1692.                 $max = count($desc);
  1693.             }
  1694.         
  1695.             for ($i = $this->_pv_periodline; $i < $max; $i++) {
  1696.                 if (strlen(trim($desc[$i])) == 0) {
  1697.                     $this->_pv_periodline = $i;
  1698.                     $i                    = $max;
  1699.                 }
  1700.             }
  1701.         }
  1702.  
  1703.         $dtype = $this->_pv_dtype;
  1704.         if ($dtype == '_pv_docblock') {
  1705.             $sdesc = new parserDesc;
  1706.             $desci = '';
  1707.             for ($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++
  1708.             ) {
  1709.                 $desci .= $desc[$i] . "\n";
  1710.             }
  1711.             $sdesc->add($this->getInlineTags($desci));
  1712.             $this->_pv_periodline++;
  1713.         
  1714.             $my_desc = new parserDesc;
  1715.             if (isset($this->_pv_dtemplate)) {
  1716.                 // copy template values if not overridden
  1717.                 if (!$this->_pv_docblock->getExplicitPackage()) {
  1718.                     if ($p = $this->_pv_dtemplate->getKeyword('package')) {
  1719.                         $this->_pv_docblock->addKeyword('package', $p);
  1720.                         $this->_pv_docblock->setExplicitPackage();
  1721.                     }
  1722.                     if ($p = $this->_pv_dtemplate->getKeyword('category')) {
  1723.                         $this->_pv_docblock->addKeyword('category', $p);
  1724.                         $this->_pv_docblock->setExplicitCategory();
  1725.                     }
  1726.                     if ($p = $this->_pv_dtemplate->getKeyword('subpackage')) {
  1727.                         $this->_pv_docblock->addKeyword('subpackage', $p);
  1728.                     }
  1729.                 }
  1730.                 $tags = $this->_pv_dtemplate->listTags();
  1731.                 foreach ($tags as $tag) {
  1732.                     $this->_pv_docblock->addTag($tag);
  1733.                 }
  1734.                 if (!count($this->_pv_docblock->params)) {
  1735.                     $this->_pv_docblock->params = $this->_pv_dtemplate->params;
  1736.                 }
  1737.                 if (!$this->_pv_docblock->return) {
  1738.                     $this->_pv_docblock->return = $this->_pv_dtemplate->return;
  1739.                 }
  1740.                 if (!$this->_pv_docblock->var) {
  1741.                     $this->_pv_docblock->var = $this->_pv_dtemplate->var;
  1742.                 }
  1743.                 $my_desc->add($this->_pv_dtemplate->sdesc);
  1744.                 $my_desc->add($this->_pv_dtemplate->desc);
  1745.             }
  1746.             //echo "i = ".$this->_pv_periodline."; i < " . count($desc) . "\n";
  1747.             $desci = '';
  1748.             for ($i = $this->_pv_periodline; $i < count($desc); $i++) {
  1749.                 // the line will not be set if it doesn't start with a *
  1750.                 if (isset($desc[$i])) {
  1751.                     $desci .= $desc[$i] . "\n";
  1752.                 }
  1753.             }
  1754.             $my_desc->add($this->getInlineTags($desci));
  1755.         } else {
  1756.             // this is a docblock template
  1757.             $sdesc = new parserDesc;
  1758.             $desci = '';
  1759.             for ($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++
  1760.             ) {
  1761.                 if (isset($desc[$i])) {
  1762.                     $desci .= $desc[$i] . "\n";
  1763.                 }
  1764.             }
  1765.             $sdesc->add($this->getInlineTags($desci));
  1766.             $this->_pv_periodline++;
  1767.         
  1768.             $my_desc = new parserDesc;
  1769.             $desci   = '';
  1770.             for ($i=$this->_pv_periodline; $i < count($desc); $i++) {
  1771.                 if (isset($desc[$i])) {
  1772.                     $desci .= $desc[$i] . "\n";
  1773.                 }
  1774.             }
  1775.             $my_desc->add($this->getInlineTags($desci));
  1776.         }
  1777.         if ($this->_pf_internal) {
  1778.             addError(PDERROR_INTERNAL_NOT_CLOSED);
  1779.             $this->_pf_internal = false;
  1780.         }
  1781.         $this->$dtype->setShortDesc($sdesc);
  1782.         $this->$dtype->setDesc($my_desc);
  1783.         unset($my_desc);
  1784.         //var_dump($this->$dtype);
  1785.         //exit;
  1786.     }
  1787.     
  1788.     /**
  1789.      * Process the tags of a DocBlock
  1790.      *
  1791.      * @param array $tags array of lines that contain all @tags
  1792.      *
  1793.      * @return void
  1794.      * @access private
  1795.      */
  1796.     function handleTags($tags)
  1797.     {
  1798.         $newtags = array();
  1799.         $curtag  = '';
  1800.         for ($i=0; $i < count($tags); $i++) {
  1801.             if (strpos(trim($tags[$i]), '@') === 0) {
  1802.                 $tags[$i] = ltrim($tags[$i]);
  1803.             }
  1804.             if (substr($tags[$i], 0, 1) == '@' && substr($tags[$i], 0, 2) != '@ '
  1805.             ) {
  1806.                 // start a new tag
  1807.                 if (!empty($curtag)) {
  1808.                     $newtags[] = $curtag;
  1809.                 }
  1810.                 $curtag = $tags[$i];
  1811.             } else {
  1812.                 $curtag .= "\n" . $tags[$i];
  1813.             }
  1814.         }
  1815.         if (!empty($curtag)) {
  1816.             $newtags[] = $curtag;
  1817.         }
  1818.         foreach ($newtags as $tag) {
  1819.             $x         = explode(' ', str_replace("\t", '    ', $tag));
  1820.             $tagname   = trim(substr(array_shift($x), 1));
  1821.             $restoftag = $x;
  1822.             if (isset($this->tagHandlers[$tagname])) {
  1823.                 $handle = $this->tagHandlers[$tagname];
  1824.             } else {
  1825.                 $handle = $this->tagHandlers['*'];
  1826.             }
  1827.             $this->$handle($tagname, $restoftag);
  1828.         }
  1829.     }
  1830.     
  1831.     /**
  1832.      * Process all inline tags in text, and convert them to their abstract
  1833.      * object representations.
  1834.      *
  1835.      * @param string|array $value complete code to search for inline tags,
  1836.      *                            if an array, it's an array of strings
  1837.      *
  1838.      * @return parserStringWithInlineTags
  1839.      * @access private
  1840.      */
  1841.     function getInlineTags($value)
  1842.     {
  1843.         if (is_array($value)) {
  1844.             $value = join("\n", $value);
  1845.         }
  1846.         global $_phpDocumentor_setting;
  1847.         $priv = (isset($_phpDocumentor_setting['parseprivate']) && 
  1848.             $_phpDocumentor_setting['parseprivate'] == 'on');
  1849.         $a    = new parserStringWithInlineTags();
  1850.         if (!$priv && $this->_pf_internal) {
  1851.             if ($x = strpos($value, '}}')) {
  1852.                 $x                  = strrpos($value, '}}');
  1853.                 $value              = substr($value, $x + 1);
  1854.                 $this->_pf_internal = false;
  1855.             } else {
  1856.                 $value = '';
  1857.             }
  1858.         } elseif ($this->_pf_internal) {
  1859.             if ($x = strpos($value, '}}')) {
  1860.                 $x     = strrpos($value, '}}');
  1861.                 $value = substr($value, 0, $x) . substr($value, $x+2);
  1862.             }
  1863.         }
  1864.         $save   = $value;
  1865.         $value  = explode('{@', $value);
  1866.         $newval = array();
  1867.         if ($priv || (!$priv && !$this->_pf_internal)) {
  1868.             // ignore anything between {@internal and }}
  1869.             $a->add($value[0]);
  1870.         }
  1871.         for ($i=1; $i < count($value); $i++) {
  1872.             if (substr($value[$i], 0, 1) == '}') {
  1873.                 if ($priv || (!$priv && !$this->_pf_internal)) {
  1874.                     // ignore anything between {@internal and }}
  1875.                     $a->add('{@' . substr($value[$i], 1));
  1876.                 }
  1877.             } elseif (substr($value[$i], 0, 2) == '*}') {
  1878.                 // used for inserting */ in code examples
  1879.                 if ($priv || (!$priv && !$this->_pf_internal)) {
  1880.                     // ignore anything between {@internal and }}
  1881.                     $a->add('*/' . substr($value[$i], 2));
  1882.                 }
  1883.             } else {
  1884.                 $save      = $value[$i];
  1885.                 $value[$i] = split("[\t ]", str_replace("\t", '    ', $value[$i]));
  1886.                 $word      = trim(array_shift($value[$i]));
  1887.                 $val       = join(' ', $value[$i]);
  1888.                 if (trim($word) == 'internal') {
  1889.                     if ($this->_pf_internal) {
  1890.                         addErrorDie(PDERROR_NESTED_INTERNAL);
  1891.                     }
  1892.                     $this->_pf_internal = true;
  1893.                     $value[$i]          = substr($save, strlen('internal') + 1);
  1894.                     if (!$value[$i]) {
  1895.                         // substr can set this to false
  1896.                         $value[$i] = '';
  1897.                     }
  1898.                     if (strpos($value[$i], '}}') !== false) {
  1899.                         $x = strrpos($value[$i], '}}');
  1900.                         // strip internal and cycle as if it were normal text.
  1901.                         $startval = substr($value[$i], 0, $x);
  1902.                         if ($priv) {
  1903.                             $a->add($startval);
  1904.                         }
  1905.                         $value[$i] = substr($value[$i], $x + 2);
  1906.                         if (!$value[$i]) {
  1907.                             $value[$i] = '';
  1908.                         }
  1909.                         $this->_pf_internal = false;
  1910.                         $a->add($value[$i]);
  1911.                         continue;
  1912.                     } elseif ($priv) {
  1913.                         $a->add($value[$i]);
  1914.                     }
  1915.                     continue;
  1916.                 }
  1917.                 if (in_array(str_replace('}', '', trim($word)),
  1918.                     $this->allowableInlineTags)
  1919.                 ) {
  1920.                     if (strpos($word, '}')) {
  1921.                         $res  = substr($word, strpos($word, '}'));
  1922.                         $word = str_replace('}', '', trim($word));
  1923.                         $val  = $res . $val;
  1924.                     }
  1925.                     if ($priv || (!$priv && !$this->_pf_internal)) {
  1926.                         // ignore anything between {@internal and }}
  1927.                         if ($word == 'source') {
  1928.                             $this->_pf_get_source = true;
  1929.                         }
  1930.                     }
  1931.                     $val = explode('}', $val);
  1932.                     if (count($val) == 1) {
  1933.                            addError(PDERROR_UNTERMINATED_INLINE_TAG,
  1934.                                $word, '', $save);
  1935.                     }
  1936.                     $rest = $val;
  1937.                     $val  = array_shift($rest);
  1938.                     $rest = join('}', $rest);
  1939.                     if (isset($this->inlineTagHandlers[$word])) {
  1940.                         $handle = $this->inlineTagHandlers[$word];
  1941.                     } else {
  1942.                         $handle = $this->inlineTagHandlers['*'];
  1943.                     }
  1944.                     $val = $this->$handle($word, $val);
  1945.                     if ($priv || (!$priv && !$this->_pf_internal)) {
  1946.                         // ignore anything between {@internal and }}
  1947.                         $a->add($val);
  1948.                     }
  1949.                     if ($this->_pf_internal) {
  1950.                         if (($x = strpos($rest, '}}')) !== false) {
  1951.                             $value[$i] = $rest;
  1952.                             $startval  = substr($value[$i], 0, $x);
  1953.                             if ((false !== $startval) && $priv) {
  1954.                                 $a->add($startval);
  1955.                             }
  1956.                             $value[$i] = substr($value[$i], $x + 2);
  1957.                             if (!$value[$i]) {
  1958.                                 $value[$i] = '';
  1959.                             }
  1960.                             $this->_pf_internal = false;
  1961.                             $a->add($value[$i]);
  1962.                         } else {
  1963.                             $rest = explode('}}', $rest);
  1964.                             if ($priv) {
  1965.                                 $a->add(array_shift($rest));
  1966.                             }
  1967.                             $this->_pf_internal = false;
  1968.                             // try this line again without internal
  1969.                             $value[$i--] = join('}}', $rest);
  1970.                             continue;
  1971.                         }
  1972.                     } else {
  1973.                         $a->add($rest);
  1974.                     }
  1975.                 } else {
  1976.                     $val = $word . ' ' . $val;
  1977.                     if ($priv || (!$priv && !$this->_pf_internal)) {
  1978.                         // ignore anything between {@internal and }}
  1979.                         $a->add('{@' . $val);
  1980.                     }
  1981.                 }
  1982.             }
  1983.         }
  1984.         return $a;
  1985.     }
  1986.  
  1987.     /**#@+
  1988.      * @param string $name name of the tag
  1989.      * @param string $value any parameters passed to the inline tag
  1990.      * @access private
  1991.      */
  1992.     /**
  1993.      * Most inline tags require no special processing
  1994.      *
  1995.      * @return mixed some type of parser_*_InlineTag object
  1996.      */
  1997.     function handleDefaultInlineTag($name, $value)
  1998.     {
  1999.         $tag = 'parser' . ucfirst($name) . 'InlineTag';
  2000.         return new $tag($value, $value);
  2001.     }
  2002.     
  2003.     /**
  2004.      * Handle the inline {@}link} tag
  2005.      *
  2006.      * @return parserLinkInlineTag
  2007.      * @tutorial tags.inlinelink.pkg
  2008.      */
  2009.     function handleLinkInlineTag($name, $value)
  2010.     {
  2011.         // support hyperlinks of any protocol
  2012.         if (is_numeric(strpos($value, '://')) || 
  2013.             (strpos(trim($value), 'mailto:') === 0)
  2014.         ) {
  2015.             $value = str_replace('\\,', '###commanana####', $value);
  2016.             if (strpos($value, ',')) {
  2017.                 $val = new parserLinkInlineTag($value, $value);
  2018.             } elseif (strpos(trim($value), ' ')) {
  2019.                 // if there is more than 1 parameter, 
  2020.                 // the stuff after the space is the hyperlink text
  2021.                 $i1   = strpos(trim($value), ' ') + 1;
  2022.                 $link = substr(trim($value), 0, $i1 - 1);
  2023.                 $text = substr(trim($value), $i1);
  2024.                 $val  = new parserLinkInlineTag($link, $text);
  2025.             } else {
  2026.                 $val = new parserLinkInlineTag($value, $value);
  2027.             }
  2028.         } else {
  2029.             $value = str_replace('\\,', '###commanana####', $value);
  2030.             if (!strpos($value, ',')) {
  2031.                 $testp = explode('#', $value);
  2032.                 if (count($testp) - 1) {
  2033.                     $val = new parserLinkInlineTag($value, $testp[1]);
  2034.                 } else {
  2035.                     $val = new parserLinkInlineTag($value, $value);
  2036.                 }
  2037.             } else {
  2038.                 $val = new parserLinkInlineTag($value, $value);
  2039.             }
  2040.         }
  2041.         return $val;
  2042.     }
  2043.     /**#@-*/
  2044.  
  2045.     /**#@+
  2046.      * @access private
  2047.      * @param string $name name of tag
  2048.      * @param array $value all words in the tag that were separated by a space ' '
  2049.      * @return void
  2050.      */
  2051.     /**
  2052.      * Most tags only need the value as a string
  2053.      *
  2054.      * @uses getInlineTags() all tag handlers check their values for inline tags
  2055.      * @uses parserDocBlock::addKeyword()
  2056.      */
  2057.     function defaultTagHandler($name, $value)
  2058.     {
  2059.         $dtype = $this->_pv_dtype;
  2060.         $this->$dtype->addKeyword($name, $this->getInlineTags(join(' ', $value)));
  2061.     }
  2062.     
  2063.     /**
  2064.      * handles the @example tag
  2065.      *
  2066.      * @tutorial tags.example.pkg
  2067.      * @uses parserDocBlock::addExample()
  2068.      */
  2069.     function exampleTagHandler($name, $value)
  2070.     {
  2071.         $dtype = $this->_pv_dtype;
  2072.         $this->$dtype->addExample($this->getInlineTags(join(' ', $value)),
  2073.             $this->_path);
  2074.     }
  2075.     
  2076.     /**
  2077.      * handles the @filesource tag
  2078.      *
  2079.      * @tutorial tags.filesource.pkg
  2080.      * @uses phpDocumentorTWordParser::getFileSource() retrieves the source for
  2081.      *       use in the @filesource tag
  2082.      * @uses parserDocBlock::addFileSource()
  2083.      */
  2084.     function filesourceTagHandler($name, $value)
  2085.     {
  2086.         $dtype = $this->_pv_dtype;
  2087.         $this->$dtype->addFileSource($this->_path, $this->_wp->getFileSource());
  2088.     }
  2089.     
  2090.     /**
  2091.      * handles the @uses tag
  2092.      *
  2093.      * @tutorial tags.uses.pkg
  2094.      * @uses parserDocBlock::addUses()
  2095.      */
  2096.     function usesTagHandler($name, $value)
  2097.     {
  2098.         $dtype = $this->_pv_dtype;
  2099.         $seel  = '';
  2100.         while ($seel == '' && count($value)) {
  2101.             $seel = array_shift($value);
  2102.         }
  2103.         $this->$dtype->addUses($this->getInlineTags($seel),
  2104.             $this->getInlineTags(join(' ', $value)));
  2105.     }
  2106.     
  2107.     /**
  2108.      * handles the @author tag
  2109.      *
  2110.      * @tutorial tags.author.pkg
  2111.      * @uses parserDocBlock::addKeyword()
  2112.      */
  2113.     function authorTagHandler($name, $value)
  2114.     {
  2115.         $dtype = $this->_pv_dtype;
  2116.         $value = join(' ', $value);
  2117.         if ((strpos($value, '<') !== false) && (strpos($value, '>') !== false)) {
  2118.             $email = substr($value, 
  2119.                 strpos($value, '<') + 1, 
  2120.                 strpos($value, '>') - strpos($value, '<') - 1);
  2121.             $value = str_replace('<' . $email . '>', 
  2122.                 '<{@link mailto:' . $email . ' ' .  $email . '}>',
  2123.                 $value);
  2124.         }
  2125.         $this->$dtype->addKeyword('author', $this->getInlineTags($value));
  2126.     }
  2127.     
  2128.     /**
  2129.      * handles the @package tag
  2130.      *
  2131.      * @tutorial tags.package.pkg
  2132.      * @uses parserDocBlock::setExplicitPackage()
  2133.      */
  2134.     function packageTagHandler($name, $value)
  2135.     {
  2136.         if (count($value) && empty($value[0])) {
  2137.             $found = false;
  2138.             // CRB - I believe this loop is correct in not having a body...
  2139.             //       I think it is only to determine the $i value needed
  2140.             //       by the one array_splice() call...
  2141.             for ($i=0; $i < count($value) && !strlen($value[$i]); $i++);
  2142.             array_splice($value, 0, $i);
  2143.         }
  2144.         $this->defaultTagHandler($name, $value);
  2145.         $dtype = $this->_pv_dtype;
  2146.         $this->$dtype->setExplicitPackage();
  2147.     }
  2148.     
  2149.     /**
  2150.      * handles the @category tag
  2151.      *
  2152.      * @tutorial tags.category.pkg
  2153.      * @uses parserDocBlock::setExplicitCategory()
  2154.      */
  2155.     function categoryTagHandler($name, $value)
  2156.     {
  2157.         if (count($value) && empty($value[0])) {
  2158.             $found = false;
  2159.             // CRB - I believe this loop is correct in not having a body...
  2160.             //       I think it is only to determine the $i value needed
  2161.             //       by the one array_splice() call...
  2162.             for ($i=0; $i < count($value) && !strlen($value[$i]); $i++);
  2163.             array_splice($value, 0, $i);
  2164.         }
  2165.         $this->defaultTagHandler($name, $value);
  2166.         $dtype = $this->_pv_dtype;
  2167.         $this->$dtype->setExplicitCategory();
  2168.     }
  2169.     
  2170.     /**
  2171.      * handles the @global tag
  2172.      *
  2173.      * @tutorial tags.global.pkg
  2174.      * @uses parserDocBlock::addFuncGlobal()
  2175.      */
  2176.     function globalTagHandler($name, $value)
  2177.     {
  2178.         $info = $this->retrieveType($value, true);
  2179.         if (!$info) {
  2180.             addError(PDERROR_MALFORMED_TAG, '@global');
  2181.         }
  2182.         $type  = $info['type'];
  2183.         $var   = $info['var'];
  2184.         $desc  = $info['desc'];
  2185.         $dtype = $this->_pv_dtype;
  2186.         if (!$var && empty($desc)) {
  2187.             if ($type{0} == '$') {
  2188.                 addError(PDERROR_MALFORMED_GLOBAL_TAG);
  2189.             }
  2190.             return $this->$dtype->addFuncGlobal($type,
  2191.                 new parserStringWithInlineTags);
  2192.         }
  2193.         if ($var) {
  2194.             // global define
  2195.             $this->_pv_global_type = $type;
  2196.             if (!empty($desc)) {
  2197.                 $var .= ' '.$desc;
  2198.             }
  2199.             $this->findGlobal(trim($var));
  2200.         } elseif (!empty($desc)) {
  2201.             // function global
  2202.             if ($type{0} == '$') {
  2203.                 addError(PDERROR_MALFORMED_GLOBAL_TAG);
  2204.             }
  2205.             $this->$dtype->addFuncGlobal($type, $this->getInlineTags($desc));
  2206.         } else {
  2207.             addError(PDERROR_MALFORMED_GLOBAL_TAG);
  2208.         }
  2209.     }
  2210.     
  2211.     /**
  2212.      * handles the @staticvar tag
  2213.      *
  2214.      * @tutorial tags.staticvar.pkg
  2215.      * @uses parserDocBlock::addStaticVar()
  2216.      */
  2217.     function staticvarTagHandler($name, $value)
  2218.     {
  2219.         $info = $this->retrieveType($value, true);
  2220.         if (!$info) {
  2221.             addError(PDERROR_MALFORMED_TAG, '@staticvar');
  2222.         }
  2223.         $type  = $info['type'];
  2224.         $var   = $info['var'];
  2225.         $desc  = $info['desc'];
  2226.         $dtype = $this->_pv_dtype;
  2227.         if (!$var && empty($desc)) {
  2228.             $this->$dtype->addStaticVar(null, $type,
  2229.                 new parserStringWithInlineTags);
  2230.         } else {
  2231.             if ($var) {
  2232.                 $this->$dtype->addStaticVar($var, $type,
  2233.                     $this->getInlineTags($desc));
  2234.             } else {
  2235.                 $this->$dtype->addStaticVar(null, $type,
  2236.                     $this->getInlineTags($desc));
  2237.             }
  2238.         }
  2239.     }
  2240.     
  2241.     /**
  2242.      * handles the @param tag
  2243.      *
  2244.      * @tutorial tags.param.pkg
  2245.      * @uses parserDocBlock::addParam()
  2246.      */
  2247.     function paramTagHandler($name, $value)
  2248.     {
  2249.         $info = $this->retrieveType($value, true);
  2250.         if (!$info) { 
  2251.             addError(PDERROR_MALFORMED_TAG, '@param');
  2252.             return;
  2253.         }
  2254.         $type  = $info['type'];
  2255.         $var   = $info['var'];
  2256.         $desc  = $info['desc'];
  2257.         $dtype = $this->_pv_dtype;
  2258.         if (!$var && empty($desc)) {
  2259.             $this->$dtype->addParam(null, $type, new parserStringWithInlineTags);
  2260.         } else {
  2261.             if ($var) {
  2262.                 $this->$dtype->addParam($var, $type, $this->getInlineTags($desc));
  2263.             } else {
  2264.                 $this->$dtype->addParam(null, $type, $this->getInlineTags($desc));
  2265.             }
  2266.         }
  2267.     }
  2268.     
  2269.     /**
  2270.      * handles the @return tag
  2271.      *
  2272.      * @tutorial tags.return.pkg
  2273.      * @uses parserDocBlock::addReturn()
  2274.      */
  2275.     function returnTagHandler($name, $value)
  2276.     {
  2277.         $info = $this->retrieveType($value, true);
  2278.         if (!$info) {
  2279.             addError(PDERROR_MALFORMED_TAG, '@return'); 
  2280.             return;
  2281.         }
  2282.         $type  = $info['type'];
  2283.         $desc  = $info['desc'];
  2284.         $dtype = $this->_pv_dtype;
  2285.         $this->$dtype->addReturn($type, $this->getInlineTags($desc));
  2286.     }
  2287.     
  2288.     /**
  2289.      * handles the @var tag
  2290.      *
  2291.      * @tutorial tags.var.pkg
  2292.      * @uses parserDocBlock::addVar()
  2293.      */
  2294.     function varTagHandler($name, $value)
  2295.     {
  2296.         $info = $this->retrieveType($value, true);
  2297.         if (!$info) {
  2298.             addError(PDERROR_MALFORMED_TAG, '@var');
  2299.         }
  2300.         $type  = $info['type'];
  2301.         $desc  = $info['desc'];
  2302.         $dtype = $this->_pv_dtype;
  2303.         $this->$dtype->addVar($type, $this->getInlineTags($desc));
  2304.     }
  2305.     
  2306.     /**
  2307.      * Handles @property(-read or -write) and @method magic tags
  2308.      *
  2309.      * @tutorial tags.method.pkg
  2310.      * @tutorial tags.property.pkg
  2311.      * @uses parserDocBlock::addProperty()
  2312.      */
  2313.     function propertyTagHandler($name, $value)
  2314.     {
  2315.         $info = $this->retrieveType($value, true);
  2316.         if (!$info) {
  2317.             addError(PDERROR_MALFORMED_TAG, '@' . $name);
  2318.         }
  2319.         $type  = $info['type'];
  2320.         $var   = $info['var'];
  2321.         $desc  = $info['desc'];
  2322.         $dtype = $this->_pv_dtype;
  2323.         $this->$dtype->addProperty($name, $var, $type, $this->getInlineTags($desc));
  2324.     }
  2325.     /**#@-*/
  2326.  
  2327.     /**#@+
  2328.      * @access private
  2329.      */
  2330.     
  2331.     /**
  2332.      * Retrieve the type portion of a @tag type description
  2333.      *
  2334.      * Tags like @param, @return and @var all have a PHP type portion in their
  2335.      * description.  Since the type may contain the expression "object blah"
  2336.      * where blah is a classname, it makes parsing out the type field complex.
  2337.      *
  2338.      * Even more complicated is the case where a tag variable can contain
  2339.      * multiple types, such as object blah|object blah2|false, and so this
  2340.      * method handles these cases.
  2341.      *
  2342.      * @param array $value       array of words that were separated by spaces
  2343.      * @param bool  $checkforvar flag to determine whether to check for the end of a
  2344.      *                           type is defined by a $varname
  2345.      *
  2346.      * @return bool|array FALSE if there is no value,
  2347.      *     or an array of Format:
  2348.      *    <pre>
  2349.      *         array(
  2350.      *             'type' => string,
  2351.      *             'var'  => false|string variable name,
  2352.      *             'desc' => rest of the tag
  2353.      *         )
  2354.      *    </pre>
  2355.      */
  2356.     function retrieveType($value, $checkforvar = false)
  2357.     {
  2358.         if (!count($value)) {
  2359.             return false;
  2360.         }
  2361.         $result = array();
  2362.         $types  = '';
  2363.         // remove empty entries resulting from extra spaces between @tag and type
  2364.         $this->_removeWhiteSpace($value, 0);
  2365.         $index = 0;
  2366.         if (trim($value[0]) == 'object') {
  2367.             $types .= array_shift($value) . ' ';
  2368.             $this->_removeWhiteSpace($value, 0);
  2369.             if (!count($value)) {
  2370.                 // was just passed "object"
  2371.                 $result = array('type' => rtrim($types), 'desc' => '');
  2372.                 if ($checkforvar) {
  2373.                     $result['var'] = false;
  2374.                 }
  2375.                 return $result;
  2376.             }
  2377.             if ($value[0]{0} == '$' || substr($value[0], 0, 2) == '&$') {
  2378.                 // was just passed "object" and the next thing is a variable name
  2379.                 $result['var']  = trim($value[0]);
  2380.                 $result['type'] = 'object';
  2381.                 array_shift($value);
  2382.                 $result['desc'] = join(' ', $value);
  2383.                 return $result;
  2384.             }
  2385.         }
  2386.         $done = false;
  2387.         do {
  2388.             // this loop checks for type|type|type
  2389.             // and for type|object classname|type|object classname2
  2390.             if (strpos($value[0], '|')) {
  2391.                 $temptypes = explode('|', $value[0]);
  2392.                 while (count($temptypes)) {
  2393.                     $type   = array_shift($temptypes);
  2394.                     $types .= $type;
  2395.                     if (count($temptypes)) {
  2396.                         $types .= '|';
  2397.                     }
  2398.                 }
  2399.                 if (trim($type) == 'object') {
  2400.                     $types .= ' ';
  2401.                     $this->_removeWhiteSpace($value, 0);
  2402.                 } else {
  2403.                     $done = true;
  2404.                 }
  2405.                 array_shift($value);
  2406.                 if (isset ($value[0]) && strlen($value[0]) && ($value[0]{0} == '$' ||
  2407.                     substr($value[0], 0, 2) == '&$')
  2408.                 ) {
  2409.                     // was just passed "object" and the next thing is a variable name
  2410.                     $result['var']  = trim($value[0]);
  2411.                     $result['type'] = $types;
  2412.                     array_shift($value);
  2413.                     $result['desc'] = join(' ', $value);
  2414.                     return $result;
  2415.                 }
  2416.             } else {
  2417.                 $types .= $value[0];
  2418.                 array_shift($value);
  2419.                 $done = true;
  2420.             }
  2421.         } while (!$done && count($value));
  2422.         $result['type'] = rtrim($types);
  2423.         $this->_removeWhiteSpace($value, 0);
  2424.         if ($checkforvar) {
  2425.             if (!count($value)) {
  2426.                 $result['var'] = false;
  2427.             } else {
  2428.                 /*
  2429.                  * check for:
  2430.                  *    variable name ($) 
  2431.                  *    var passed by reference (&$)
  2432.                  *    method name (only used by magic method)
  2433.                  */
  2434.                 if (substr($value[0], 0, 1) == '$' ||
  2435.                     substr($value[0], 0, 2) == '&$' ||
  2436.                     substr($value[0], -2, 2) == '()'
  2437.                 ) {
  2438.                     $result['var'] = trim($value[0]);
  2439.                     array_shift($value);
  2440.                 } else {
  2441.                     $result['var'] = false;
  2442.                 }
  2443.             }
  2444.         }
  2445.         $result['desc'] = join(' ', $value);
  2446.         return $result;
  2447.     }
  2448.     
  2449.     /**
  2450.      * remove whitespace from a value
  2451.      *
  2452.      * @param array   &$value array of string
  2453.      * @param integer $index  index to seek non-whitespace to
  2454.      *
  2455.      * @return void
  2456.      */
  2457.     function _removeWhiteSpace(&$value, $index)
  2458.     {
  2459.         if (count($value) > $index && empty($value[$index])) {
  2460.             $found = false;
  2461.             // CRB - I believe this loop is correct in not having a body...
  2462.             //       I think it is only to determine the $i value needed
  2463.             //       by the one array_splice() call...
  2464.             for ($i=$index; $i < count($value) && !strlen($value[$i]); $i++);
  2465.             array_splice($value, $index, $i - $index);
  2466.         }
  2467.     }
  2468.     
  2469.     /**
  2470.      * Retrieve all the tokens that represent the definition of the global variable
  2471.      *
  2472.      * {@source}
  2473.      *
  2474.      * @param string $name the global variable to find
  2475.      *
  2476.      * @return void
  2477.      */
  2478.     function findGlobal($name)
  2479.     {
  2480.         $tokens = token_get_all('<?php ' . $name);
  2481.         $tokens = array_slice($tokens, 1);
  2482.         $this->_wp->findGlobal($tokens);
  2483.         $this->_pv_findglobal = $name;
  2484.     }
  2485.  
  2486.     /**
  2487.      * this function checks whether parameter $word 
  2488.      * is a token for pushing a new event onto the Event Stack.
  2489.      *
  2490.      * @param string $word   the word to check
  2491.      * @param int    $pevent the event to push
  2492.      *
  2493.      * @return mixed returns false, or the event number
  2494.      */
  2495.     function checkEventPush($word, $pevent)
  2496.     {
  2497.         if (is_array($word) && $word[0] == T_STRING) {
  2498.             $word = $word[1];
  2499.         }
  2500.         if (is_array($word)) {
  2501.             $pushEvent = &$this->tokenpushEvent;
  2502.             $word      = $word[0];
  2503.         } else {
  2504.             $pushEvent = &$this->wordpushEvent;
  2505.             $word      = strtolower($word);
  2506.         }
  2507.         $e = false;
  2508.         if (isset($pushEvent[$pevent])) {
  2509.             if (isset($pushEvent[$pevent][$word])) {
  2510.                 $e = $pushEvent[$pevent][$word];
  2511.             }
  2512.         }
  2513.         if ($e) {
  2514.             $this->_event_stack->pushEvent($e);
  2515.             return $e;
  2516.         } else {
  2517.             return false;
  2518.         }
  2519.     }
  2520.  
  2521.     /**
  2522.      * this function checks whether parameter $word 
  2523.      * is a token for popping the current event off of the Event Stack.
  2524.      *
  2525.      * @param string $word   the word to check
  2526.      * @param int    $pevent the event to pop
  2527.      *
  2528.      * @return mixed returns false, or the event number popped off of the stack
  2529.      */
  2530.     function checkEventPop($word, $pevent)
  2531.     {
  2532.         if (is_array($word) && $word[0] == T_STRING) {
  2533.             $word = $word[1];
  2534.         }
  2535.         if (is_array($word)) {
  2536.             $popEvent = &$this->tokenpopEvent;
  2537.             $word     = $word[0];
  2538.         } else {
  2539.             $popEvent = &$this->wordpopEvent;
  2540.             $word     = strtolower($word);
  2541.         }
  2542.         if (!isset($popEvent[$pevent])) {
  2543.             return false;
  2544.         }
  2545.         if (in_array($word, $popEvent[$pevent])) {
  2546.             return $this->_event_stack->popEvent();
  2547.         } else {
  2548.             return false;
  2549.         }
  2550.     }
  2551.  
  2552.     /**
  2553.      * returns the token from the $word array
  2554.      *
  2555.      * @param mixed $word the token array
  2556.      *
  2557.      * @return mixed the token from the array,
  2558.      *               or FALSE if it's not an array
  2559.      */
  2560.     function getToken($word)
  2561.     {
  2562.         if (is_array($word)) {
  2563.             return $word[0];
  2564.         }
  2565.         return false;
  2566.     }
  2567.     
  2568.     /**
  2569.      * setup the parser tokens, and the pushEvent/popEvent arrays
  2570.      *
  2571.      * @return void
  2572.      * @see $tokens, $pushEvent, $popEvent
  2573.      */
  2574.     function setupStates()
  2575.     {
  2576.         unset($this->_wp);
  2577.         $this->_wp                     = new phpDocumentorTWordParser;
  2578.         $this->_pv_class               = null;
  2579.         $this->_pv_cur_class           = null;
  2580.         $this->_pv_define              = null;
  2581.         $this->_pv_define_name         = null;
  2582.         $this->_pv_define_value        = null;
  2583.         $this->_pv_define_params_data  = null;
  2584.         $this->_pv_dtype               = null;
  2585.         $this->_pv_docblock            = null;
  2586.         $this->_pv_dtemplate           = null;
  2587.         $this->_pv_func                = null;
  2588.         $this->_pv_findglobal          = null;
  2589.         $this->_pv_global_name         = null;
  2590.         $this->_pv_global_val          = null;
  2591.         $this->_pv_globals             = null;
  2592.         $this->_pv_global_count        = null;
  2593.         $this->_pv_include_params_data = null;
  2594.         $this->_pv_include_name        = null;
  2595.         $this->_pv_include_value       = null;
  2596.         $this->_pv_linenum             = null;
  2597.         $this->_pv_periodline          = null;
  2598.         $this->_pv_paren_count         = 0;
  2599.         $this->_pv_statics             = null;
  2600.         $this->_pv_static_count        = null;
  2601.         $this->_pv_static_val          = null;
  2602.         $this->_pv_quote_data          = null;
  2603.         $this->_pv_function_data       = null;
  2604.         $this->_pv_var                 = null;
  2605.         $this->_pv_varname             = null;
  2606.         $this->_pv_const               = null;
  2607.         $this->_pv_constname           = null;
  2608.         $this->_pv_function_param_type = null;
  2609.         $this->_pf_definename_isset    = false;
  2610.         $this->_pf_includename_isset   = false;
  2611.         $this->_pf_get_source          = false;
  2612.         $this->_pf_getting_source      = false;
  2613.         $this->_pf_in_class            = false;
  2614.         $this->_pf_in_define           = false;
  2615.         $this->_pf_in_global           = false;
  2616.         $this->_pf_in_include          = false;
  2617.         $this->_pf_in_var              = false;
  2618.         $this->_pf_in_const            = false;
  2619.         $this->_pf_funcparam_val       = false;
  2620.         $this->_pf_quote_active        = false;
  2621.         $this->_pf_reset_quote_data    = true;
  2622.         $this->_pf_useperiod           = false;
  2623.         $this->_pf_var_equals          = false;
  2624.         $this->_pf_const_equals        = false;
  2625.         $this->_event_stack            = new EventStack;
  2626.     }
  2627.     
  2628.     /**
  2629.      * Creates the state arrays
  2630.      *
  2631.      * @return void
  2632.      */
  2633.     function setupEventStates()
  2634.     {
  2635.         if (!defined('T_DOC_COMMENT')) {
  2636.             define('T_DOC_COMMENT', T_DOC_COMMENT);
  2637.         }
  2638.         /**************************************************************/
  2639.  
  2640.         $this->wordpushEvent[PARSER_EVENT_LOGICBLOCK]  = 
  2641.             array(
  2642.                 "{" => PARSER_EVENT_LOGICBLOCK,
  2643.                 '"' => PARSER_EVENT_QUOTE,
  2644.             );
  2645.         $this->tokenpushEvent[PARSER_EVENT_LOGICBLOCK] =
  2646.             array(
  2647.                 T_GLOBAL                   => PARSER_EVENT_FUNC_GLOBAL,
  2648.                 T_STATIC                   => PARSER_EVENT_STATIC_VAR,
  2649.                 T_START_HEREDOC            => PARSER_EVENT_EOFQUOTE,
  2650.                 T_CURLY_OPEN               => PARSER_EVENT_LOGICBLOCK,
  2651.                 T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
  2652.             );
  2653.  
  2654.         $this->wordpopEvent[PARSER_EVENT_LOGICBLOCK]  = array("}");
  2655.         $this->tokenpopEvent[PARSER_EVENT_LOGICBLOCK] = array(T_CURLY_OPEN);
  2656.         /**************************************************************/
  2657.  
  2658.         $this->tokenpushEvent[PARSER_EVENT_NOEVENTS] = 
  2659.             array(
  2660.                 T_OPEN_TAG => PARSER_EVENT_PHPCODE,
  2661.             );
  2662.  
  2663.         /**************************************************************/
  2664.  
  2665.         $this->tokenpopEvent[PARSER_EVENT_EOFQUOTE] = array(T_END_HEREDOC);
  2666.         /**************************************************************/
  2667.  
  2668.         $this->tokenpushEvent[PARSER_EVENT_PHPCODE] = 
  2669.             array(
  2670.                 T_FUNCTION     => PARSER_EVENT_FUNCTION,
  2671.                 T_ABSTRACT     => PARSER_EVENT_ACCESS_MODIFIER,
  2672.                 T_CLASS        => PARSER_EVENT_CLASS,
  2673.                 T_INTERFACE    => PARSER_EVENT_CLASS,
  2674.                 T_INCLUDE_ONCE => PARSER_EVENT_INCLUDE,
  2675.                 T_INCLUDE      => PARSER_EVENT_INCLUDE,
  2676.                 T_REQUIRE      => PARSER_EVENT_INCLUDE,
  2677.                 T_REQUIRE_ONCE => PARSER_EVENT_INCLUDE,
  2678.                 T_COMMENT      => PARSER_EVENT_DOCBLOCK,
  2679.                 T_DOC_COMMENT  => PARSER_EVENT_DOCBLOCK,
  2680.                 //"/**#@+"       => PARSER_EVENT_DOCBLOCK_TEMPLATE,
  2681.                 //"/**#@-*/"     => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
  2682.                 T_CLOSE_TAG    => PARSER_EVENT_OUTPHP,
  2683.             );
  2684.         $this->wordpushEvent[PARSER_EVENT_PHPCODE]  =
  2685.             array(
  2686.                 "define" => PARSER_EVENT_DEFINE,
  2687.             );
  2688.         /**************************************************************/
  2689.  
  2690.         $this->tokenpopEvent[PARSER_EVENT_OUTPHP] = array(T_OPEN_TAG);
  2691.         /**************************************************************/
  2692.  
  2693.         $this->wordpushEvent[PARSER_EVENT_FUNCTION]  =
  2694.             array(
  2695.                 '{' => PARSER_EVENT_LOGICBLOCK,
  2696.                 '(' => PARSER_EVENT_FUNCTION_PARAMS,
  2697.             );
  2698.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION] =
  2699.             array(
  2700.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2701.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2702.             );
  2703.  
  2704.         $this->wordpopEvent[PARSER_EVENT_FUNCTION] = array("}",';');
  2705.         /**************************************************************/
  2706.  
  2707.         $this->wordpopEvent[PARSER_EVENT_QUOTE] = array('"');
  2708.         /**************************************************************/
  2709.  
  2710.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
  2711.             array(
  2712.                 T_VARIABLE    => PARSER_EVENT_FUNCTION_PARAM_VAR,
  2713.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2714.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2715.             );
  2716.         $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS]   = array(")");
  2717.         /**************************************************************/
  2718.  
  2719.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR] =
  2720.             array(
  2721.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2722.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2723.                 T_DOC_COMMENT              => PARSER_EVENT_COMMENT,
  2724.                 T_ARRAY                    => PARSER_EVENT_ARRAY,
  2725.             );
  2726.         $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAM_VAR]  =
  2727.             array(
  2728.                 '"' => PARSER_EVENT_QUOTE,
  2729.                 "'" => PARSER_EVENT_QUOTE,
  2730.             );
  2731.         $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAM_VAR]   = array(",", ")");
  2732.         /**************************************************************/
  2733.  
  2734.         $this->tokenpushEvent[PARSER_EVENT_ARRAY] = 
  2735.             array(
  2736.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2737.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2738.             );
  2739.         $this->wordpopEvent[PARSER_EVENT_ARRAY]   = array(")");
  2740.         /**************************************************************/
  2741.  
  2742.         $this->tokenpushEvent[PARSER_EVENT_VAR_ARRAY] = 
  2743.             array(
  2744.                 T_COMMENT     => PARSER_EVENT_VAR_ARRAY_COMMENT,
  2745.                 T_DOC_COMMENT => PARSER_EVENT_VAR_ARRAY_COMMENT,
  2746.             );
  2747.         $this->wordpopEvent[PARSER_EVENT_VAR_ARRAY]   = array(")");
  2748.         /**************************************************************/
  2749.  
  2750.         $this->tokenpushEvent[PARSER_EVENT_FUNC_GLOBAL] =
  2751.             array(
  2752.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2753.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2754.             );
  2755.         $this->wordpopEvent[PARSER_EVENT_FUNC_GLOBAL]   = array(";");
  2756.         /**************************************************************/
  2757.  
  2758.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR] =
  2759.             array(
  2760.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2761.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2762.                 T_DOC_COMMENT              => PARSER_EVENT_COMMENT,
  2763.             );
  2764.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR]  =
  2765.             array(
  2766.                 "=" => PARSER_EVENT_STATIC_VAR_VALUE,
  2767.             );
  2768.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR]   = array(";");
  2769.         /**************************************************************/
  2770.  
  2771.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR_VALUE] = 
  2772.             array(
  2773.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2774.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2775.                 T_DOC_COMMENT              => PARSER_EVENT_COMMENT,
  2776.                 T_ARRAY                    => PARSER_EVENT_ARRAY,
  2777.             );
  2778.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR_VALUE]  =
  2779.             array(
  2780.                 '"' => PARSER_EVENT_QUOTE,
  2781.                 "'" => PARSER_EVENT_QUOTE,
  2782.             );
  2783.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR_VALUE]   = array(";",",");
  2784.         /**************************************************************/
  2785.  
  2786.         $this->tokenpushEvent[PARSER_EVENT_DEFINE] = 
  2787.             array(
  2788.                 T_COMMENT                  => PARSER_EVENT_COMMENT,
  2789.                 T_DOC_COMMENT              => PARSER_EVENT_COMMENT,
  2790.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2791.             );
  2792.         $this->wordpushEvent[PARSER_EVENT_DEFINE]  = 
  2793.             array(
  2794.                 "(" => PARSER_EVENT_DEFINE_PARAMS,
  2795.             );
  2796.         $this->wordpopEvent[PARSER_EVENT_DEFINE]   = array(";");
  2797.         /**************************************************************/
  2798.  
  2799.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE] = 
  2800.             array(
  2801.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2802.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2803.             );
  2804.         $this->wordpushEvent[PARSER_EVENT_INCLUDE]  = 
  2805.             array(
  2806.                 "(" => PARSER_EVENT_INCLUDE_PARAMS,
  2807.             );
  2808.         $this->wordpopEvent[PARSER_EVENT_INCLUDE]   = array(";");
  2809.         /**************************************************************/
  2810.  
  2811.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS] = 
  2812.             array(
  2813.                 T_COMMENT       => PARSER_EVENT_COMMENT,
  2814.                 T_DOC_COMMENT   => PARSER_EVENT_COMMENT,
  2815.                 T_START_HEREDOC => PARSER_EVENT_EOFQUOTE,
  2816.             );
  2817.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS]  = 
  2818.             array(
  2819.                 "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2820.                 '"' => PARSER_EVENT_QUOTE,
  2821.                 "'" => PARSER_EVENT_QUOTE,
  2822.             );
  2823.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS]   = array(")");
  2824.         /**************************************************************/
  2825.  
  2826.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS] = 
  2827.             array(
  2828.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2829.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2830.             );
  2831.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS]  = 
  2832.             array(
  2833.                 "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2834.             );
  2835.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS]   = array(")");
  2836.         /**************************************************************/
  2837.  
  2838.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =
  2839.             array(
  2840.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2841.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2842.             );
  2843.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS]  =
  2844.             array(
  2845.                 "(" => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2846.                 '"' => PARSER_EVENT_QUOTE,
  2847.                 "'" => PARSER_EVENT_QUOTE,
  2848.             );
  2849.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS]   = array(")");
  2850.         /**************************************************************/
  2851.  
  2852.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =
  2853.             array(
  2854.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2855.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2856.             );
  2857.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS]  =
  2858.             array(
  2859.                 "(" => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2860.             );
  2861.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS]   = array(")");
  2862.         /**************************************************************/
  2863.  
  2864.         $this->tokenpushEvent[PARSER_EVENT_VAR] = 
  2865.             array(
  2866.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2867.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2868.                 T_ARRAY       => PARSER_EVENT_VAR_ARRAY,
  2869.             );
  2870.         $this->wordpopEvent[PARSER_EVENT_VAR]   = array(";");
  2871.         /**************************************************************/
  2872.  
  2873.         $this->tokenpushEvent[PARSER_EVENT_CLASS_CONSTANT] = 
  2874.             array(
  2875.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2876.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2877.                 T_ARRAY       => PARSER_EVENT_VAR_ARRAY,
  2878.             );
  2879.         $this->wordpopEvent[PARSER_EVENT_CLASS_CONSTANT]   = array(";");
  2880.         /**************************************************************/
  2881.  
  2882.         $this->wordpopEvent[PARSER_EVENT_IMPLEMENTS] = array('{');
  2883.         /**************************************************************/
  2884.  
  2885.         $this->tokenpushEvent[PARSER_EVENT_CLASS] = 
  2886.             array(
  2887.                 T_ABSTRACT    => PARSER_EVENT_ACCESS_MODIFIER,
  2888.                 T_PUBLIC      => PARSER_EVENT_ACCESS_MODIFIER,
  2889.                 T_PRIVATE     => PARSER_EVENT_ACCESS_MODIFIER,
  2890.                 T_PROTECTED   => PARSER_EVENT_ACCESS_MODIFIER,
  2891.                 T_STATIC      => PARSER_EVENT_ACCESS_MODIFIER,
  2892.                 T_IMPLEMENTS  => PARSER_EVENT_IMPLEMENTS,
  2893.                 T_CONST       => PARSER_EVENT_CLASS_CONSTANT,
  2894.                 T_FUNCTION    => PARSER_EVENT_FUNCTION,
  2895.                 T_VAR         => PARSER_EVENT_VAR,
  2896.                 T_COMMENT     => PARSER_EVENT_DOCBLOCK,
  2897.                 T_DOC_COMMENT => PARSER_EVENT_DOCBLOCK,
  2898.                 T_CLOSE_TAG   => PARSER_EVENT_OUTPHP,
  2899.             );
  2900.         $this->wordpopEvent[PARSER_EVENT_CLASS]   = array("}");
  2901.         /**************************************************************/
  2902.  
  2903.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_GLOBAL] = 
  2904.             array(
  2905.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2906.                 T_DOC_COMMENT => PARSER_EVENT_COMMENT,
  2907.             );
  2908.         $this->wordpushEvent[PARSER_EVENT_DEFINE_GLOBAL]  = 
  2909.             array(
  2910.                 "=" => PARSER_EVENT_GLOBAL_VALUE,
  2911.             );
  2912.         $this->wordpopEvent[PARSER_EVENT_DEFINE_GLOBAL]   = array(";");
  2913.         /**************************************************************/
  2914.  
  2915.         $this->tokenpushEvent[PARSER_EVENT_GLOBAL_VALUE] = 
  2916.             array(
  2917.                 T_ARRAY         => PARSER_EVENT_ARRAY,
  2918.                 T_COMMENT       => PARSER_EVENT_COMMENT,
  2919.                 T_DOC_COMMENT   => PARSER_EVENT_COMMENT,
  2920.                 T_START_HEREDOC => PARSER_EVENT_EOFQUOTE,
  2921.             );
  2922.         $this->wordpushEvent[PARSER_EVENT_GLOBAL_VALUE]  =
  2923.             array(
  2924.                 '"' => PARSER_EVENT_QUOTE,
  2925.                 "'" => PARSER_EVENT_QUOTE,
  2926.             );
  2927.         $this->wordpopEvent[PARSER_EVENT_GLOBAL_VALUE]   = array(";");
  2928.     }
  2929.     
  2930.     /**
  2931.      * initializes all the setup
  2932.      *
  2933.      * @param mixed &$data the data parser (?)
  2934.      *
  2935.      * @return void
  2936.      */
  2937.     function configWordParser(&$data)
  2938.     {
  2939.         $this->_wp->setup($data);
  2940.         $this->_wp->setWhitespace(false);
  2941.     }
  2942.  
  2943.     /**#@-*/
  2944.  
  2945. }
  2946. ?>
  2947.