home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / phpDocumentorTParser.inc < prev    next >
Encoding:
Text File  |  2004-03-24  |  85.0 KB  |  2,350 lines

  1. <?php
  2. //
  3. // +------------------------------------------------------------------------+
  4. // | phpDocumentor                                                          |
  5. // +------------------------------------------------------------------------+
  6. // | Copyright (c) 2000-2003 Joshua Eichorn, Gregory Beaver                 |
  7. // | Email         jeichorn@phpdoc.org, cellog@phpdoc.org                   |
  8. // | Web           http://www.phpdoc.org                                    |
  9. // | Mirror        http://phpdocu.sourceforge.net/                          |
  10. // | PEAR          http://pear.php.net/package-info.php?pacid=137           |
  11. // +------------------------------------------------------------------------+
  12. // | This source file is subject to version 3.00 of the PHP License,        |
  13. // | that is available at http://www.php.net/license/3_0.txt.               |
  14. // | If you did not receive a copy of the PHP license and are unable to     |
  15. // | obtain it through the world-wide-web, please send a note to            |
  16. // | license@php.net so we can mail you a copy immediately.                 |
  17. // +------------------------------------------------------------------------+
  18. //
  19.  
  20. /**
  21.  * @package phpDocumentor
  22.  * @subpackage Parsers
  23.  * @author Gregory Beaver <cellog@users.sourceforge.net>
  24.  * @version $Revision: 1.48.2.13 $
  25.  */
  26. /**
  27.  * Tokenizer-based parser for PHP source code
  28.  * @package phpDocumentor
  29.  * @subpackage Parsers
  30.  * @author Gregory Beaver <cellog@users.sourceforge.net>
  31.  * @version $Revision: 1.48.2.13 $
  32.  */
  33. class phpDocumentorTParser extends Parser
  34. {
  35.     /**#@+
  36.      * @access private
  37.      */
  38.     /**
  39.      * @var EventStack
  40.      */
  41.     var $_event_stack;
  42.     /**
  43.      * last event triggered before the current event
  44.      * @var integer
  45.      */
  46.     var $_last_pevent;
  47.     /**
  48.      * last word parsed
  49.      * @var integer
  50.      */
  51.     var $_last_word;
  52.     /**
  53.      * full path of the currently parsed file
  54.      * @var string
  55.      */
  56.     var $_path;
  57.     /**#@-*/
  58.     /**#@+
  59.      * Parser Variables
  60.      * @access private
  61.      */
  62.     var $_pv_class;
  63.     var $_pv_cur_class;
  64.     var $_pv_define;
  65.     var $_pv_define_name;
  66.     var $_pv_define_value;
  67.     var $_pv_define_params_data;
  68.     var $_pv_dtype;
  69.     var $_pv_docblock;
  70.     var $_pv_dtemplate;
  71.     var $_pv_func;
  72.     var $_pv_findglobal;
  73.     var $_pv_global_name;
  74.     var $_pv_global_val;
  75.     var $_pv_globals;
  76.     var $_pv_global_count;
  77.     var $_pv_include_params_data;
  78.     var $_pv_include_name;
  79.     var $_pv_include_value;
  80.     var $_pv_linenum;
  81.     var $_pv_periodline;
  82.     var $_pv_paren_count = 0;
  83.     var $_pv_statics;
  84.     var $_pv_static_count;
  85.     var $_pv_static_val;
  86.     var $_pv_quote_data;
  87.     var $_pv_function_data;
  88.     var $_pv_var;
  89.     var $_pv_varname;
  90.     var $_pv_var_value;
  91.     /**#@-*/
  92.     /**#@+
  93.      * Parser Flags
  94.      * @access private
  95.      */
  96.     var $_pf_definename_isset = false;
  97.     var $_pf_includename_isset = false;
  98.     var $_pf_get_source = false;
  99.     var $_pf_getting_source = false;
  100.     var $_pf_internal = false;
  101.     var $_pf_in_class = false;
  102.     var $_pf_in_define = false;
  103.     var $_pf_in_global = false;
  104.     var $_pf_in_include = false;
  105.     var $_pf_in_var = false;
  106.     var $_pf_funcparam_val = false;
  107.     var $_pf_quote_active = false;
  108.     var $_pf_reset_quote_data = true;
  109.     var $_pf_useperiod = false;
  110.     var $_pf_set_var_value = false;
  111.     var $_pf_var_equals = false;
  112.     /**#@-*/
  113.     /**
  114.      * relative path of the parsed file from the base parse directory
  115.      * @var string
  116.      */
  117.     var $source_location;
  118.     var $eventHandlers = array(
  119.                                 PARSER_EVENT_ARRAY => 'handleArray',
  120.                                 PARSER_EVENT_CLASS => 'handleClass',
  121.                                 PARSER_EVENT_COMMENT => 'handleComment',
  122.                                 PARSER_EVENT_DOCBLOCK_TEMPLATE => 'handleDocBlockTemplate',
  123.                                 PARSER_EVENT_END_DOCBLOCK_TEMPLATE => 'handleEndDocBlockTemplate',
  124.                                 PARSER_EVENT_LOGICBLOCK => 'handleLogicBlock',
  125.                                 PARSER_EVENT_NOEVENTS => 'defaultHandler',
  126.                                 PARSER_EVENT_OUTPHP => 'defaultHandler',
  127.                                 PARSER_EVENT_DEFINE => 'handleDefine',
  128.                                 PARSER_EVENT_DEFINE_PARAMS => 'handleDefineParams',
  129.                                 PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS => 'handleDefineParamsParenthesis',
  130.                                 PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS => 'handleIncludeParamsParenthesis',
  131.                                 PARSER_EVENT_DOCBLOCK => 'handleDocBlock',
  132.                                 PARSER_EVENT_TAGS => 'handleTags',
  133.                                 PARSER_EVENT_DESC => 'handleDesc',
  134.                                 PARSER_EVENT_DOCKEYWORD => 'handleTag',
  135.                                 PARSER_EVENT_DOCKEYWORD_EMAIL => 'handleDockeywordEmail',
  136.                                 PARSER_EVENT_EOFQUOTE => 'handleEOFQuote',
  137.                                 PARSER_EVENT_FUNCTION => 'handleFunction',
  138.                                 PARSER_EVENT_FUNCTION_PARAMS => 'handleFunctionParams',
  139.                                 PARSER_EVENT_FUNC_GLOBAL => 'handleFuncGlobal',
  140.                                 PARSER_EVENT_DEFINE_GLOBAL => 'handleGlobal',
  141.                                 PARSER_EVENT_GLOBAL_VALUE => 'handleGlobalValue',
  142.                                 PARSER_EVENT_INLINE_DOCKEYWORD => 'handleInlineDockeyword',
  143.                                 PARSER_EVENT_INCLUDE => 'handleInclude',
  144.                                 PARSER_EVENT_INCLUDE_PARAMS => 'handleIncludeParams',
  145.                                 PARSER_EVENT_QUOTE => 'handleQuote',
  146.                                 PARSER_EVENT_PHPCODE => 'handlePhpCode',
  147.                                 PARSER_EVENT_SINGLEQUOTE => 'handleSingleQuote',
  148.                                 PARSER_EVENT_STATIC_VAR => 'handleStaticVar',
  149.                                 PARSER_EVENT_STATIC_VAR_VALUE => 'handleStaticValue',
  150.                                 PARSER_EVENT_VAR => 'handleVar',
  151.     );
  152.     
  153.     var $inlineTagHandlers = array(
  154.                                 '*' => 'handleDefaultInlineTag',
  155.                                 'link' => 'handleLinkInlineTag',
  156.                                 );
  157.     
  158.     function phpDocumentorTParser()
  159.     {
  160.         $this->allowableTags = $GLOBALS['_phpDocumentor_tags_allowed'];
  161.         $this->allowableInlineTags = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];
  162.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWLINENUM,$GLOBALS['phpDocumentor_errors']);
  163.         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWFILE,$GLOBALS['phpDocumentor_errors']);
  164.         $this->tagHandlers['author'] = 'authorTagHandler';
  165.         $this->tagHandlers['filesource'] = 'filesourceTagHandler';
  166.         $this->setupEventStates();
  167.     }
  168.     
  169.     /**
  170.      * Parse a new file
  171.      *
  172.      * @param    string    $parse_data
  173.      * @param    string    $path
  174.      * @param    int    $base    number of directories to drop off the bottom when creating names using path
  175.      * @staticvar    integer    used for recursion limiting if a handler for an event is not found
  176.      * @return    bool
  177.      */
  178.     function parse (&$parse_data, $path, $base = 0, $packages = false)
  179.     {
  180.         global $_phpDocumentor_options;
  181.         static $endrecur = 0;
  182.         $this->setupStates();
  183.         if (strlen($parse_data) == 0)
  184.         {
  185.             return false;
  186.         }
  187.  
  188.         $this->configWordParser($parse_data);
  189.         // initialize variables so E_ALL error_reporting doesn't complain
  190.         $pevent = 0;
  191.         $word = 0;
  192.  
  193.         $page = new ParserPage;
  194.         $page->setSource($this->_wp->getFileSource());
  195.         $page->setPath($path);
  196.         $this->_path = $path;
  197.         $page->setPackageOutput($packages);
  198.         $page->setFile(basename($path));
  199.         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWFILE,basename($path));
  200.         //$name = str_replace("/","_",dirname($path)) . "_" . array_shift(explode(".",$page->getFile()));
  201.         // fc@fc.clever-soft.com 11/29/2001
  202.         $name = str_replace(PATH_DELIMITER,"_",dirname($path)) . "_" .  str_replace(".","_",$page->getFile());
  203.         $tmp = explode("_",$name);
  204.         $name = str_replace(':','_',implode("_",array_slice($tmp,$base)));
  205.         // if base is '', drive letter is present in windows
  206.  
  207.         $page->setName($name);
  208.         $temploc = $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER. implode(PATH_DELIMITER,
  209.             array_slice(explode(PATH_DELIMITER,$path),$base));
  210.         
  211.         if ($temploc == $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER) $temploc .= $path;
  212.         
  213.         $this->source_location = $source_location = $temploc;
  214.         $page->setSourceLocation($source_location);
  215.  
  216.         $this->publishEvent(PHPDOCUMENTOR_EVENT_PAGE,$page);
  217.         unset($page);
  218.  
  219.         do
  220.         {
  221.             $lpevent = $pevent;
  222.             $pevent = $this->_event_stack->getEvent();
  223.             if ($lpevent != $pevent)
  224.             {
  225.                 $this->_last_pevent = $lpevent;
  226.             }
  227.  
  228.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent + 100));
  229.  
  230.             $this->_pv_last_word = $word;
  231.             $word = $this->_wp->getWord();
  232.             if (isset($this->_pv_findglobal) && $word == $this->_pv_findglobal)
  233.             {
  234.                 $this->_last_pevent = $pevent;
  235.                 $this->_event_stack->pushEvent($pevent = PARSER_EVENT_DEFINE_GLOBAL);
  236.             }
  237.             // in wordparser, have to keep track of lines
  238.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM, $this->_wp->linenum);
  239.             if ($this->_pf_get_source)
  240.             {
  241.                 if ($word[0] == T_FUNCTION)
  242.                 {
  243.                     $this->_wp->retrievesource($word);
  244.                     $this->_pf_get_source = false;
  245.                     $this->_pf_getting_source = true;
  246.                 }
  247.             }
  248.  
  249.             if (0)//PHPDOCUMENTOR_DEBUG == true)
  250.             {
  251.                 echo "LAST: ";
  252.                 if (is_array($this->_pv_last_word))
  253.                 {
  254.                     echo token_name($this->_pv_last_word[0]). ' => |'.htmlspecialchars($this->_pv_last_word[1]);
  255.                 } else echo "|" . $this->_pv_last_word;
  256.                 echo "|\n";
  257.                 echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";
  258.                 echo "LASTPEVENT: " . $this->getParserEventName($this->_last_pevent) . "\n";
  259.                 echo $this->_wp->getPos() . ": ";
  260.                 if (is_array($word))
  261.                 {
  262.                     echo token_name($word[0]).' => |'.htmlspecialchars($word[1]);
  263.                 } else echo '|'.htmlspecialchars($word);
  264.                 echo "|\n-------------------\n\n\n";
  265.             }
  266.             if (0)//$this->_pf_getting_source && ($pevent == PARSER_EVENT_DOCBLOCK) || ($pevent == PARSER_EVENT_NOEVENTS))
  267.             {
  268.                 addError(PDERROR_SOURCE_TAG_FUNCTION_NOT_FOUND);
  269.                 // throw away source
  270.                 $this->_wp->getSource();
  271.             }
  272.             if (isset($this->eventHandlers[$pevent]))
  273.             {
  274.                 $handle = $this->eventHandlers[$pevent];
  275.                 $this->$handle($word, $pevent);
  276.             } else
  277.             {
  278.                 debug('WARNING: possible error, no handler for event number '.$pevent);
  279.                 if ($endrecur++ == 25)
  280.                 {
  281.                     die("FATAL ERROR, recursion limit reached");
  282.                 }
  283.             }
  284.         } while (!($word === false));
  285.         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_PAGE);
  286.     }
  287.  
  288.     /**#@+
  289.      * @access private
  290.      */
  291.     /**
  292.      * handler for COMMENT
  293.      */
  294.     function handleComment($word, $pevent)
  295.     {
  296.         $this->_wp->backupPos();
  297.         $this->_event_stack->popEvent();
  298.     }
  299.     /**
  300.      * handler for PHPCODE.
  301.      * this handler recognizes the <code><?</code> php processor directive, and begins parsing php code
  302.      */
  303.     
  304.     function handlePhpCode($word, $pevent)
  305.     {
  306.         $e = $this->checkEventPush( $word, $pevent);
  307.         if (isset($this->_pv_findglobal) && $e)
  308.         {
  309.             if ($e != PARSER_EVENT_DEFINE_GLOBAL && $e != PARSER_EVENT_ARRAY && $e != PARSER_EVENT_QUOTE && $e != PARSER_EVENT_SINGLEQUOTE && $e != PARSER_EVENT_COMMENT && $e != PARSER_EVENT_COMMENTBLOCK)
  310.             {
  311.                 addError(PDERROR_GLOBAL_NOT_FOUND,$this->_pv_findglobal);
  312.                 $this->_wp->findGlobal(false);
  313.                 unset($this->_pv_findglobal);
  314.             }
  315.         }
  316.     }
  317.     
  318.     /**
  319.      * handler for FUNC_GLOBAL.
  320.      * this handler recognizes "global $var1, $var2" declarations in a function, and parses them
  321.      */
  322.     
  323.     function handleFuncGlobal($word, $pevent)
  324.     {
  325.         if ($this->checkEventPop($word, $pevent))
  326.         {
  327.             return;
  328.         }
  329.         if (!$this->checkEventPush($word, $pevent))
  330.         {
  331.             if ($word == ',')
  332.             { // another variable
  333.                 $this->_pv_global_count++;
  334.             } else
  335.             {
  336.                 if (!isset($this->_pv_globals[$this->_pv_global_count]))
  337.                 $this->_pv_globals[$this->_pv_global_count] = '';
  338. //                if (!empty($this->_pv_globals[$this->_pv_global_count])) $this->_pv_global_count++;
  339.                 if (is_array($word)) $word = $word[1];
  340.                 $this->_pv_globals[$this->_pv_global_count] .= $word;
  341.             }
  342.         }
  343.     }
  344.     
  345.     /**
  346.      * handler for STATIC_VAR.
  347.      * this handler recognizes "static $var1, $var2 = 6" declarations in a function, and parses them
  348.      */
  349.     
  350.     function handleStaticVar($word, $pevent)
  351.     {
  352.         if ($this->checkEventPop($word, $pevent))
  353.         {
  354.             $this->_pv_static_count++;
  355.             return;
  356.         }
  357.         if (!$this->checkEventPush($word, $pevent))
  358.         {
  359.             if ($word == ',')
  360.             {
  361.                 $this->_pv_static_count++;
  362.                 return;
  363.             }
  364.             if (!isset($this->_pv_statics[$this->_pv_static_count]))
  365.             $this->_pv_statics[$this->_pv_static_count] = '';
  366.             if (!empty($this->_pv_statics[$this->_pv_static_count])) $this->_pv_static_count++;
  367.             if (is_array($word)) $word = $word[1];
  368.             $this->_pv_statics[$this->_pv_static_count] = $word;
  369.         }
  370.     }
  371.     
  372.     /**
  373.      * handler for STATIC_VAR_VALUE.
  374.      * this handler parses the 6 in "static $var1, $var2 = 6"
  375.      */
  376.     
  377.     function handleStaticValue($word, $pevent)
  378.     {
  379.         if ($this->checkEventPush($word, $pevent))
  380.         {
  381.             return;
  382.         }
  383.         if (!isset($this->_pv_static_val[$this->_pv_static_count])) $this->_pv_static_val[$this->_pv_static_count] = '';
  384.         if ($this->_last_pevent == PARSER_EVENT_QUOTE)
  385.         {
  386.             $this->_pv_static_val[$this->_pv_static_count] .= $this->_pv_quote_data;
  387.             unset($this->_pv_quote_data);
  388.         }
  389.         if ($this->_last_pevent == PARSER_EVENT_ARRAY)
  390.         {
  391.             $this->_pv_static_val[$this->_pv_static_count] .= $this->_pv_function_data;
  392.             $this->_pv_function_data = '';
  393.         }
  394.         if ($this->checkEventPop($word, $pevent))
  395.         {
  396.             $this->_pv_static_val[$this->_pv_static_count] = trim($this->_pv_static_val[$this->_pv_static_count]);
  397.             $this->_wp->backupPos($word);
  398.             return;
  399.         } else
  400.         {
  401.             if (is_array($word)) $word = $word[1];
  402.             $this->_pv_static_val[$this->_pv_static_count] .= $word;
  403.         }
  404.     }
  405.     
  406.     /**
  407.      * handler for LOGICBLOCK
  408.      *
  409.      * Logic Blocks are the stuff between { and } in a function/method.  A
  410.      * logic block can clearly contain other logic blocks, as in:
  411.      *
  412.      * <code>
  413.      * function test($a)
  414.      * {
  415.      *    if (testcondition)
  416.      *    { // nested logic block
  417.      *    }
  418.      * }
  419.      * </code>
  420.      *
  421.      * So, the exit portion of the logic block handler must check to see if the
  422.      * logic block being exited is the top-level, and it does this by retrieving
  423.      * the last event from the stack.  If it is a function (and not a logic block)
  424.      * then it backs up the word parser so that the function will exit properly.
  425.      *
  426.      * {@source 11}
  427.      */
  428.     
  429.     function handleLogicBlock($word, $pevent)
  430.     {
  431.         $a = $this->checkEventPush( $word, $pevent);
  432.         if ($this->checkEventPop($word,$pevent))
  433.         {
  434.             $e = $this->_event_stack->popEvent();
  435.             $this->_event_stack->pushEvent($e);
  436.             if ($e == PARSER_EVENT_FUNCTION)
  437.             {
  438.                 $this->_wp->backupPos(); 
  439.             }
  440.         }
  441.     }
  442.     
  443.     /**
  444.      * handler for FUNCTION.
  445.      * this handler recognizes function declarations, and parses them.  The body
  446.      * of the function is parsed by handleLogicBlock()
  447.      * @see handleLogicBlock()
  448.      */
  449.     
  450.     function handleFunction($word, $pevent)
  451.     {
  452.         if ($e = $this->checkEventPush( $word, $pevent))
  453.         {
  454.             $this->_pv_function_data = '';
  455.             if ($e == PARSER_EVENT_FUNCTION_PARAMS && !is_object($this->_pv_func))
  456.             {
  457.                 addErrorDie(PDERROR_FUNCTION_HAS_NONAME);
  458.             }
  459.             if ($e == PARSER_EVENT_COMMENT || $e == PARSER_EVENT_COMMENTBLOCK || $e == PARSER_EVENT_FUNCTION_PARAMS) return;
  460.         }
  461.     
  462.         if (!isset($this->_pv_func)) $this->_pv_func = false;
  463.         if (! is_object($this->_pv_func)) 
  464.         {
  465.             $this->_pv_globals = array();
  466.             $this->_pv_global_count = $this->_pv_static_count = 0;
  467.             if ($this->_pf_in_class)
  468.             $this->_pv_func = new parserMethod($this->_pv_cur_class); 
  469.             else
  470.             $this->_pv_func = new parserFunction;
  471.             $this->_pv_func->setLineNumber($this->_wp->linenum + 1);
  472.             if (is_string($word) && $word == '&')
  473.             $this->_pv_func->setReturnsReference();
  474.             if (is_array($word) && $word[0] == T_STRING)
  475.             $this->_pv_func->setName($word[1]);
  476.         } else
  477.         {
  478.             if ($this->_pv_func->getReturnsReference())
  479.             {
  480.                 if (is_array($word) && $word[0] == T_STRING)
  481.                 {
  482.                     $this->_pv_func->setName($word[1]);
  483.                 }
  484.             }
  485.         }
  486.         if ($this->checkEventPop($word,$pevent)) 
  487.         {
  488.             $this->_pv_func->setEndLineNumber($this->_wp->linenum + 1);
  489.             $this->_pv_func->addGlobals($this->_pv_globals);
  490.             $this->_pv_func->addStatics($this->_pv_statics,$this->_pv_static_val);
  491.             $this->_pv_globals = array();
  492.             $this->_pv_global_count = 0;
  493.             if ($this->_pf_getting_source)
  494.             {
  495.                 $x = $this->_wp->getSource();
  496.                 $this->_pv_func->addSource($x);
  497.                 $this->_pf_get_source = false;
  498.                 $this->_pf_getting_source = false;
  499.             }
  500.             $this->publishEvent(PHPDOCUMENTOR_EVENT_FUNCTION,$this->_pv_func); 
  501.             $this->_pv_func = false; 
  502.             unset($this->_pv_quote_data); // subtle bug fixed by this, sometimes string
  503.                                           // from function body was picked up
  504.                                           // by the next function as a default value
  505.                                           // for a parameter!
  506.         } 
  507.     }
  508.  
  509.     /**
  510.      * Helper function for {@link handleFunctionParams()}
  511.      *
  512.      * This function adds a new parameter to the parameter list
  513.      */
  514.     function endFunctionParam($word)
  515.     {
  516.         if (isset($this->_pv_quote_data))
  517.         {
  518.             $this->_pv_function_data .= $this->_pv_quote_data;
  519.             unset($this->_pv_quote_data);
  520.         }
  521.         if (isset($this->_pv_function_param))
  522.         {
  523.             $this->_pv_func->addParam($this->_pv_function_param,$this->_pv_function_data, $this->_pf_funcparam_val);
  524.             unset($this->_pv_function_param);
  525.             $this->_pv_function_data = '';
  526.             $this->_pf_funcparam_val = false;
  527.         }
  528.     }
  529.     /**
  530.      * handler for FUNCTION_PARAMS.
  531.      * this handler recognizes the parameters of a function within parentheses like function(param, param = default_value)
  532.      * and parses them
  533.      * @see endFunctionParam()
  534.      */
  535.     
  536.     function handleFunctionParams($word, $pevent)
  537.     {
  538.         //echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->_pv_last_word."|\n";
  539.         //echo "function_param = '".$this->_pv_function_param."'\n";
  540.         //echo "function_data = '".$this->_pv_function_data."'\n";
  541.         $e1 = $this->checkEventPush( $word, $pevent); 
  542.  
  543.         if (!$e1)
  544.         {
  545.             if ($word == ',' || $this->checkEventPop($word,$pevent))
  546.             {
  547.                 $this->endFunctionParam($word);
  548.             } elseif ($word == '=')
  549.             {
  550.                 $this->_pf_funcparam_val = true;
  551.             } else
  552.             {
  553.                 if ($this->_pf_funcparam_val)
  554.                 {
  555.                     if (isset($this->_pv_quote_data))
  556.                     {
  557.                         $this->_pv_function_data .= $this->_pv_quote_data;
  558.                         unset($this->_pv_quote_data);
  559.                     }
  560.                     if (is_array($word)) $word = $word[1];
  561.                     $this->_pv_function_data .= $word;
  562.                 } else
  563.                 {
  564.                     if (!isset($this->_pv_function_param)) $this->_pv_function_param = '';
  565.                     if (is_array($word)) $word = $word[1];
  566.                     $this->_pv_function_param .= $word;
  567.                 }
  568.             }
  569.         } elseif ($e1 == PARSER_EVENT_ARRAY)
  570.         {
  571.             $this->_wp->setWhiteSpace(true);
  572.         }
  573.     }
  574.  
  575.     /**
  576.      * handler for ARRAY.
  577.      * this event handler parses arrays in default values of function and var definitions
  578.      */
  579.     
  580.     function handleArray($word, $pevent)
  581.     {
  582.         $e = $this->checkEventPush( $word, $pevent);
  583.         if ($e) return;
  584.  
  585.         if (!isset($this->_pv_function_data) || (isset($this->_pv_function_data) && empty($this->_pv_function_data)))
  586.         {
  587.             $this->_pv_function_data = "array";
  588.         }
  589.  
  590.         if ($word == '(' && $this->_pv_paren_count++)
  591.         { // need extra parentheses help
  592.             $this->_event_stack->pushEvent($pevent);
  593.         }
  594.         if (is_array($word))
  595.         {
  596.             $this->_pv_function_data .= $word[1];
  597.         } else
  598.         $this->_pv_function_data .= $word;
  599.         //echo "function_data = |$this->_pv_function_data|\n";
  600.  
  601.         if ($this->checkEventPop($word,$pevent))
  602.         {
  603.             $this->_pv_paren_count--;
  604.             $this->_wp->setWhiteSpace(false);
  605.         }
  606.     }
  607.  
  608.     /**
  609.      * handler for QUOTE.
  610.      * this handler recognizes strings defined with double quotation marks (")
  611.      * and single quotation marks and handles them correctly
  612.      * in any place that they legally appear in php code
  613.      */
  614.     
  615.     function handleQuote($word, $pevent)
  616.     {
  617.         if ($this->_pv_last_word == '"' || $this->_pv_last_word == "'" && $this->_last_pevent != PARSER_EVENT_QUOTE)
  618.         {
  619.             $save = $word;
  620.             if (is_array($word)) $word = $word[1];
  621.             $this->_pv_quote_data = $this->_pv_last_word . $word;
  622.             $this->_pf_quote_active = true;
  623.             $this->checkEventPop($save, $pevent);
  624.         } elseif (!$this->_pf_quote_active)
  625.         {
  626.             $this->_pv_quote_data = $this->_pv_last_word[1];
  627.             $this->_event_stack->popEvent();
  628.             $this->_wp->backupPos();
  629.             return;
  630.         }
  631.         $save = $word;
  632.         if (is_array($word)) $word = $word[1];
  633.         $this->_pv_quote_data .= $word;
  634.         if ($this->checkEventPop($save, $pevent))
  635.         {
  636.             $this->_pf_quote_active = false;
  637.         }
  638.     }
  639.  
  640.     /**
  641.      * handler for INCLUDE.
  642.      * this handler recognizes include/require/include_once/include_once statements, and publishes the
  643.      * data to Render
  644.      */
  645.     
  646.     function handleInclude($word, $pevent)
  647.     {
  648.         if (!$this->_pf_in_include)
  649.         {
  650.             $this->_pv_linenum = $this->_wp->linenum;
  651.         }
  652.         $this->_pf_in_include = true;
  653.         $a = $this->checkEventPush( $word, $pevent);
  654.         if (!$this->_pf_includename_isset)
  655.         {
  656.             $this->_pf_includename_isset = true;
  657.             $w = $this->_pv_last_word;
  658.             if (is_array($w)) $w = $w[1];
  659.             $this->_pv_include_name = $w;
  660.             if ($a)
  661.             $this->_pv_include_value = '';
  662.             else
  663.             {
  664.                 if (is_array($word)) $word = $word[1];
  665.                 $this->_pv_include_value = $word;
  666.             }
  667.             unset($this->_pv_quote_data);
  668.         } else
  669.         {
  670.             if (!$a)
  671.             {
  672.                 if (empty($this->_pv_include_params_data))
  673.                 {
  674.                     if ($word != ';')
  675.                     {
  676.                         if (is_array($word)) $word = $word[1];
  677.                         $this->_pv_include_value .= $word;
  678.                     }
  679.                 }
  680.             } else
  681.             {
  682.                 $this->_pv_include_params_data = '';
  683.             }
  684.         }
  685.  
  686.         if ($this->checkEventPop($word,$pevent))
  687.         {
  688.             $this->_pv_include = new parserInclude;
  689.             $this->_pv_include->setLineNumber($this->_pv_linenum + 1);
  690.             $this->_pf_in_include = false;
  691.             $this->_pv_include->setName($this->_pv_include_name);
  692.             $this->_pv_include->setValue($this->_pv_include_value);
  693.             $this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE,$this->_pv_include);
  694.             $this->_pf_includename_isset = false;
  695.             unset($this->_pv_include);
  696.             unset($this->_pv_include_name);
  697.             unset($this->_pv_include_value);
  698.             unset($this->_pv_include_params_data);
  699.         }
  700.     }
  701.     
  702.     /**
  703.      * handler for INCLUDE_PARAMS.
  704.      * this handler parses the contents of ( ) in include/require/include_once/include_once statements
  705.      */
  706.     
  707.     function handleIncludeParams($word, $pevent)
  708.     {
  709.         $e = $this->checkEventPush( $word, $pevent);
  710.         if ($e == PARSER_EVENT_COMMENT) return;
  711.         
  712.         if(!isset($this->_pv_include_params_data)) $this->_pv_include_params_data = '';
  713.         
  714.         if ($this->checkEventPop($word,$pevent))
  715.         {
  716.             if (!empty($this->_pv_include_params_data))
  717.             $this->_pv_include_value = $this->_pv_include_params_data;
  718.             else
  719.             {
  720.                 $w = $this->_pv_last_word;
  721.                 if (is_array($w)) $w = $w[1];
  722.                 $this->_pv_include_value = $w;
  723.             }
  724.         }
  725.         if (is_array($word)) $word = $word[1];
  726.         $this->_pv_include_params_data .= $word;
  727.     }
  728.     
  729.     /**
  730.      * handler for INCLUDE_PARAMS_PARENTHESIS.
  731.      * this handler takes all parenthetical statements within file in:
  732.      * include statement include(file), and handles them properly
  733.      */
  734.     
  735.     function handleIncludeParamsParenthesis($word, $pevent)
  736.     {
  737.         $this->checkEventPush( $word, $pevent);
  738.         $this->checkEventPop( $word, $pevent);
  739.         if (is_array($word)) $word = $word[1];
  740.         $this->_pv_include_params_data .= $word;
  741.     }
  742.  
  743.     /**
  744.      * handler for DEFINE.
  745.      * handles define(constant, value); statements
  746.      */
  747.     
  748.     function handleDefine($word, $pevent)
  749.     {
  750.         if (!$this->_pf_in_define)
  751.         {
  752.             $this->_pv_linenum = $this->_wp->linenum + 1;
  753.         }
  754.         $this->_pf_in_define = true;
  755.         $this->checkEventPush( $word, $pevent);
  756.  
  757.         $this->_pf_definename_isset = false;
  758.         $this->_pv_define_params_data = '';
  759.         unset($this->_pv_quote_data);
  760.         if ($this->checkEventPop($word,$pevent))
  761.         {
  762.             $this->_pf_in_define = false;
  763.             $this->_pv_define = new parserDefine;
  764.             $this->_pv_define->setLineNumber($this->_pv_linenum);
  765.             $this->_pv_define->setName($this->_pv_define_name);
  766.             $this->_pv_define->setValue($this->_pv_define_value);
  767.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DEFINE,$this->_pv_define);
  768.             $this->_pf_definename_isset = false;
  769.             unset($this->_pv_define);
  770.             unset($this->_pv_define_name);
  771.             unset($this->_pv_define_value);
  772.             $this->_pf_in_define = false;
  773.             $this->_pv_define_params_data = '';
  774.         }
  775.     }
  776.     
  777.     /**
  778.      * handler for DEFINE_PARAMS.
  779.      * handles the parsing of constant and value in define(constant, value);
  780.      */
  781.     
  782.     function handleDefineParams($word, $pevent)
  783.     {
  784.         $e = $this->checkEventPush( $word, $pevent);
  785.         if ($e && $e != PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS) return;
  786.         
  787.         if(!isset($this->_pv_define_params_data)) $this->_pv_define_params_data = '';
  788.         
  789.         if ($this->checkEventPop($word,$pevent))
  790.         {
  791.             if ($this->_last_pevent == PARSER_EVENT_QUOTE)
  792.             {
  793.                 $this->_pv_define_params_data .= $this->_pv_quote_data;
  794.                 unset($this->_pv_quote_data);
  795.             }
  796.             if (is_array($word)) $word = $word[1];
  797.             if (!empty($this->_pv_define_params_data))
  798.             {
  799.                 //echo $this->_pv_define_params_data."\n";
  800.                 $this->_pv_define_value = $this->_pv_define_params_data;
  801.             }
  802.             else
  803.             {
  804.                 $w = $this->_pv_last_word;
  805.                 if (is_array($this->_pv_last_word)) $w = $this->_pv_last_word[1];
  806.                 if (!empty($w))
  807.                 {
  808.                     $this->_pv_define_value = $w;
  809.                 }
  810.                 else
  811.                 {
  812.                     $this->_pv_define_value = "";
  813.                 }
  814.             }
  815.         }
  816.         if ($this->_pf_definename_isset)
  817.         {
  818.             if (is_array($word)) $word = $word[1];
  819.             $this->_pv_define_params_data .= $word;
  820.         } else
  821.         {
  822.             if ($word != ",")
  823.             {
  824.                 if (is_array($word)) $word = $word[1];
  825.                 $this->_pv_define_params_data .= $word;
  826.             } else
  827.             {
  828.                 if (substr($this->_pv_define_params_data,0,1) ==
  829.                     substr($this->_pv_define_params_data,strlen($this->_pv_define_params_data) - 1) &&
  830.                     in_array(substr($this->_pv_define_params_data,0,1),array('"',"'")))
  831.                 { // remove leading and ending quotation marks if there are only two
  832.                     $a = substr($this->_pv_define_params_data,0,1);
  833.                     $b = substr($this->_pv_define_params_data,1,strlen($this->_pv_define_params_data) - 2);
  834.                     if (strpos($b,$a) === false)
  835.                     {
  836.                         $this->_pv_define_params_data = $b;
  837.                     }
  838.                 }
  839.                 $this->_pf_definename_isset = true;
  840.                 $this->_pv_define_name = $this->_pv_define_params_data;
  841.                 $this->_pv_define_params_data = '';
  842.             }
  843.         }
  844.     }
  845.     
  846.     /**
  847.      * handler for DEFINE_PARAMS_PARENTHESIS.
  848.      * this handler takes all parenthetical statements within constant or value in:
  849.      * define(constant, value) of a define statement, and handles them properly
  850.      */
  851.     
  852.     function handleDefineParamsParenthesis($word, $pevent)
  853.     {
  854.         $e = $this->checkEventPush( $word, $pevent);
  855.         $this->checkEventPop( $word, $pevent);
  856.         if ($this->_last_pevent == PARSER_EVENT_QUOTE)
  857.         {
  858.             $this->_pv_define_params_data .= $this->_pv_quote_data;
  859.             unset($this->_pv_quote_data);
  860.         }
  861.         if (is_array($word)) $word = $word[1];
  862.         $this->_pv_define_params_data .= $word;
  863.     }
  864.  
  865.  
  866.     /**
  867.      * handler for CLASS.
  868.      * this handler parses a class statement
  869.      */
  870.     
  871.     function handleClass($word, $pevent)
  872.     {
  873.         $this->_pf_in_class = true;
  874.         $a = $this->checkEventPush( $word, $pevent);
  875.  
  876.         if (!isset($this->_pv_class)) $this->_pv_class = false;
  877.         if (!is_subclass_of($this->_pv_class,"parserBase"))
  878.         {
  879.             $this->_pv_class = new parserClass;
  880.             $this->_pv_class->setLineNumber($this->_wp->linenum + 1);
  881.             $this->_pv_class->setname($word[1]);
  882.             $this->_pv_cur_class = $word[1];
  883.             $this->_pv_class->setSourceLocation($this->source_location);
  884.         }
  885.  
  886.         if (is_array($this->_pv_last_word) && $this->_pv_last_word[0] == T_EXTENDS)
  887.         {
  888.             $this->_pv_class->setExtends($word[1]);
  889.         }
  890.  
  891.         if ($word == "{")
  892.         {
  893.             $this->publishEvent(PHPDOCUMENTOR_EVENT_CLASS,$this->_pv_class);
  894.         }
  895.         //echo $this->wp->getPos() . ": |$word|\n";
  896.         if ($this->checkEventPop($word,$pevent))
  897.         {
  898.             $this->_pv_class->setEndLineNumber($this->_wp->linenum + 1);
  899.             $this->_pf_in_class = false;
  900.             // throw an event when class is done
  901.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,STATE_END_CLASS);
  902.             $this->_pv_class = false;
  903.         }
  904.     }
  905.  
  906.     /**
  907.      * handler for VAR.
  908.      * handle a var $varname = default_value; or var $varname; statement in a class definition
  909.      */
  910.     
  911.     function handleVar($word, $pevent)
  912.     {
  913.         if (!$this->_pf_in_var)
  914.         {
  915.             $this->_pf_set_var_value = false;
  916.             $this->_pv_var_value = '';
  917.             $this->_pv_linenum = $this->_wp->linenum + 1;
  918.         }
  919.         $this->_pf_in_var = true;
  920.         //echo $word."\n";
  921.         $e = $this->checkEventPush( $word, $pevent);
  922.         
  923.         if (!isset($this->_pv_var)) $this->_pv_var = false;
  924.         if ($word == '=' || $word == ';' || $word == ',')
  925.         {
  926.             $this->_wp->setWhitespace(true);
  927.             $this->_pf_var_equals = true;
  928.             $this->_pv_var = new parserVar($this->_pv_cur_class);
  929.             $this->_pv_var->setName($this->_pv_varname);
  930.         }
  931.         if ($this->_last_pevent == PARSER_EVENT_ARRAY)
  932.         {
  933.             if (isset($this->_pv_function_data))
  934.             $this->_pv_var->setValue($this->_pv_function_data);
  935.             $this->_pf_set_var_value = true;
  936.             unset($this->_pv_function_data);
  937.         } elseif ($this->_pf_var_equals && $word != ';' && $word != '=' && $word != ',' && !$e)
  938.         {
  939.             if (is_array($word)) $word = $word[1];
  940.             $this->_pv_var_value .= $word;
  941.         }
  942.         if ($word == ',')
  943.         {
  944.             if (!$this->_pf_set_var_value)
  945.             $this->_pv_var->setValue($this->_pv_var_value);
  946.             $this->_pf_set_var_value = false;
  947.             unset($this->_pv_var_value);
  948.             $this->_pv_var->setEndLineNumber($this->_wp->linenum + 1);
  949.             $this->_pv_var->setLineNumber($this->_pv_linenum);
  950.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR,$this->_pv_var);
  951.             unset($this->_pv_var);
  952.             $this->_pf_in_var = false;
  953.             $this->_pf_var_equals = false;
  954.             $this->_pv_varname = '';
  955.             return;
  956.         }
  957.         if ($this->checkEventPop($word,$pevent))
  958.         {
  959.             $this->_wp->setWhitespace(false);
  960.             if (!$this->_pf_set_var_value)
  961.             $this->_pv_var->setValue($this->_pv_var_value);
  962.             $this->_pf_set_var_value = false;
  963.             unset($this->_pv_var_value);
  964.             $this->_pv_var->setEndLineNumber($this->_wp->linenum + 1);
  965.             $this->_pv_var->setLineNumber($this->_pv_linenum);
  966.             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR,$this->_pv_var);
  967.             unset($this->_pv_var);
  968.             $this->_pf_in_var = false;
  969.             $this->_pf_var_equals = false;
  970.             $this->_pv_varname = '';
  971.             return;
  972.         }
  973.         if ($word[0] == T_VARIABLE)
  974.         {
  975.             $this->_pv_varname = $word[1];
  976.         }
  977.  
  978.     }
  979.     
  980.     /**
  981.      * Handler for the {@tutorial phpDocumentor.howto.pkg#using.command-line.javadocdesc}
  982.      * command-line switch DocBlocks.
  983.      */
  984.     function JavaDochandleDocblock($word, $pevent)
  985.     {
  986.         $this->commonDocBlock($word, $pevent, 'handleJavaDocDesc');
  987.     }
  988.     
  989.     /**
  990.      * Handler for normal DocBlocks
  991.      */
  992.     function handleDocBlock($word, $pevent)
  993.     {
  994.         $this->commonDocBlock($word, $pevent, 'handleDesc');
  995.     }
  996.     
  997.     /**
  998.      * Common DocBlock Handler for both JavaDoc-format and normal DocBlocks
  999.      */
  1000.     function commonDocBlock($word, $pevent, $deschandler)
  1001.     {
  1002.         $this->_wp->backupPos();
  1003.         $this->_event_stack->popEvent();
  1004.         $word = $this->_pv_last_word[1];
  1005.         $dtype = '_pv_docblock';
  1006.         if (strpos($word,'/**') !== 0)
  1007.         { // not a docblock
  1008. //            $this->_wp->backupPos();
  1009.             $this->_event_stack->pushEvent(PARSER_EVENT_COMMENT);
  1010.             return;
  1011.         }
  1012.         if ($word == '/**#@-*/')
  1013.         { // stop using docblock template
  1014.             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE);
  1015.             unset($this->_pv_dtemplate);
  1016.             return;
  1017.         }
  1018.         if (strpos($word,'/**#@+') === 0)
  1019.         { // docblock template definition
  1020.             $dtype = '_pv_dtemplate';
  1021.             // strip /**#@+ and */
  1022.             $word = substr($word,6).'*';
  1023.             $word = substr($word,0,strlen($word) - 2);
  1024.         } else
  1025.         {
  1026.             // strip /** and */
  1027.             $word = substr($word,2);
  1028.             $word = substr($word,0,strlen($word) - 2);
  1029.         }
  1030.         $lines = explode("\n",trim($word));
  1031.         $go = count($lines);
  1032.         for($i=0;$i<$go;$i++)
  1033.         {
  1034.             if (substr(trim($lines[$i]),0,1) != '*') unset($lines[$i]);
  1035.             else
  1036.             $lines[$i] = substr(trim($lines[$i]),1); // remove leading "* "
  1037.         }
  1038.         // remove empty lines
  1039.         $lines = explode("\n",trim(join("\n",$lines)));
  1040.         for($i = 0;$i<count($lines);$i++)
  1041.         {
  1042.             if (substr(trim($lines[$i]),0,1) == '@' && substr(trim($lines[$i]),0,2) != '@ ')
  1043.             {
  1044.                 $tagindex = $i;
  1045.                 $i = count($lines);
  1046.             }
  1047.         }
  1048.         if (isset($tagindex))
  1049.         {
  1050.             $tags = array_slice($lines,$tagindex);
  1051.             $desc = array_slice($lines,0,$tagindex);
  1052.         } else
  1053.         {
  1054.             $tags = array();
  1055.             $desc = $lines;
  1056.         }
  1057. //        var_dump($desc,$tags);
  1058.         $this->$dtype = new parserDocBlock;
  1059.         $this->$dtype->setLineNumber($this->_wp->_docblock_linenum + 1);
  1060.         $this->$dtype->setEndLineNumber($this->_wp->linenum);
  1061.         $this->_pv_dtype = $dtype;
  1062.         $this->$deschandler($desc);
  1063.         $this->handleTags($tags);
  1064.         if ($dtype == '_pv_docblock')
  1065.         {
  1066.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->$dtype);
  1067.             $this->$dtype = new parserDocBlock();
  1068.         } else
  1069.         {
  1070.             $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE,$this->$dtype);
  1071.         }
  1072.     }
  1073.     
  1074.     /**
  1075.      * Handles JavaDoc descriptions
  1076.      */
  1077.     function handleJavaDocDesc($desc)
  1078.     {
  1079.         unset($this->_pv_periodline);
  1080.         $this->_pf_useperiod = false;
  1081.         foreach($desc as $i => $line)
  1082.         {
  1083.             $line = trim($line);
  1084.             if (!isset($this->_pv_periodline) && substr($line,strlen($line) - 1) == '.')
  1085.             {
  1086.                 $this->_pv_periodline = $i;
  1087.                 $this->_pf_useperiod = true;
  1088.             }
  1089.         }
  1090.         if (!isset($this->_pv_periodline)) $this->_pv_periodline = 0;
  1091.  
  1092.         $dtype = $this->_pv_dtype;
  1093.         if ($dtype == '_pv_docblock')
  1094.         {
  1095.             $save = $desc;
  1096.             // strip leading <p>
  1097.             if (strpos($desc[0],'<p>') === 0) $desc[0] = substr($desc[0],3);
  1098.             $sdesc = new parserDesc;
  1099.             $desci = '';
  1100.             for($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++)
  1101.             {
  1102.                 if (strpos($desc[$i],'.') !== false)
  1103.                 {
  1104.                     $desci .= substr($desc[$i],0,strpos($desc[$i],'.') + 1);
  1105.                 } else
  1106.                 {
  1107.                     $desci .= $desc[$i];
  1108.                 }
  1109.                 $desci .= "\n";
  1110.             }
  1111.             $sdesc->add($this->getInlineTags($desci));
  1112.             $desc = $save;
  1113.         
  1114.             $my_desc = new parserDesc;
  1115.             if (isset($this->_pv_dtemplate))
  1116.             {
  1117.                 // copy template values if not overridden
  1118.                 if (!$this->_pv_docblock->getExplicitPackage())
  1119.                 {
  1120.                     if ($p = $this->_pv_dtemplate->getKeyword('package'))
  1121.                     {
  1122.                         $this->_pv_docblock->addKeyword('package',$p);
  1123.                         $this->_pv_docblock->setExplicitPackage();
  1124.                     }
  1125.                     if ($p = $this->_pv_dtemplate->getKeyword('category'))
  1126.                     {
  1127.                         $this->_pv_docblock->addKeyword('category',$p);
  1128.                         $this->_pv_docblock->setExplicitCategory();
  1129.                     }
  1130.                     if ($p = $this->_pv_dtemplate->getKeyword('subpackage'))
  1131.                     {
  1132.                         $this->_pv_docblock->addKeyword('subpackage',$p);
  1133.                     }
  1134.                 }
  1135.                 $tags = $this->_pv_dtemplate->listTags();
  1136.                 foreach($tags as $tag)
  1137.                 {
  1138.                     $this->_pv_docblock->addTag($tag);
  1139.                 }
  1140.                 if (!count($this->_pv_docblock->params)) $this->_pv_docblock->params = $this->_pv_dtemplate->params;
  1141.                 $my_desc->add($this->_pv_dtemplate->desc);
  1142.             }
  1143. //            echo "i = ".$this->_pv_periodline."; i < " . count($desc) . "\n";
  1144.             $desci = '';
  1145.             for($i = 0; $i < count($desc); $i++)
  1146.             {
  1147.                 // the line will not be set if it doesn't start with a *
  1148.                 if (isset($desc[$i]))
  1149.                 {
  1150.                     $desci .= $desc[$i]."\n";
  1151.                 }
  1152.             }
  1153.             $my_desc->add($this->getInlineTags($desci));
  1154.         } else
  1155.         {
  1156.             $sdesc = new parserDesc;
  1157.             $save = $desc;
  1158.             // strip leading <p>
  1159.             if (strpos($desc[0],'<p>') === 0) $desc[0] = substr($desc[0],3);
  1160.             $desci = '';
  1161.             for($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++)
  1162.             {
  1163.                 if (strpos($desc[$i],'.') !== false)
  1164.                 {
  1165.                     $desci .= substr($desc[$i],0,strpos($desc[$i],'.') + 1);
  1166.                 } else
  1167.                 {
  1168.                     $desci .= $desc[$i];
  1169.                 }
  1170.                 $desci .= "\n";
  1171.             }
  1172.             $sdesc->add($this->getInlineTags($desci));
  1173.             $desc = $save;
  1174.         
  1175.             $my_desc = new parserDesc;
  1176.             $desci = '';
  1177.             for($i=0; $i < count($desc); $i++)
  1178.             {
  1179.                 if (isset($desc[$i]))
  1180.                     $desci .= $desci[$i]."\n";
  1181.             }
  1182.             $my_desc->add($this->getInlineTags($desci));
  1183.         }
  1184.         
  1185.         if ($this->_pf_internal)
  1186.         {
  1187.             addError(PDERROR_INTERNAL_NOT_CLOSED);
  1188.             $this->_pf_internal = false;
  1189.         }
  1190.         $this->$dtype->setShortDesc($sdesc);
  1191.         $this->$dtype->setDesc($my_desc);
  1192.         unset($my_desc);
  1193. //        var_dump($this->$dtype);
  1194. //        exit;
  1195.     }
  1196.     
  1197.     /**
  1198.      * Process the Long Description of a DocBlock
  1199.      * @param array array of lines containing the description with leading
  1200.      *              asterisk "*" stripped off.
  1201.      */
  1202.     function handleDesc($desc)
  1203.     {
  1204.         unset($this->_pv_periodline);
  1205.         $this->_pf_useperiod = false;
  1206.         foreach($desc as $i => $line)
  1207.         {
  1208.             $line = trim($line);
  1209.             if (!isset($this->_pv_periodline) && substr($line,strlen($line) - 1) == '.')
  1210.             {
  1211.                 $this->_pv_periodline = $i;
  1212.                 $this->_pf_useperiod = true;
  1213.             }
  1214.         }
  1215.         if (!isset($this->_pv_periodline)) $this->_pv_periodline = 0;
  1216.         if ($this->_pv_periodline > 3)
  1217.         {
  1218.             $this->_pf_useperiod = false;
  1219.         } else
  1220.         {
  1221.             for($i = 0; $i < $this->_pv_periodline; $i++)
  1222.             {
  1223.                 if (strlen($desc[$i]) == 0 && isset($desc[$i - 1]) && strlen($desc[$i - 1]))
  1224.                 {
  1225.                     $this->_pv_periodline = $i;
  1226.                 }
  1227.             }
  1228.         }
  1229.         for($i=0;$i <= $this->_pv_periodline && $i < count($desc);$i++)
  1230.         {
  1231.             if (!strlen(trim($desc[$i]))) $this->_pf_useperiod = false;
  1232.         }
  1233.         // figure out the shortdesc
  1234.         if ($this->_pf_useperiod === false)
  1235.         {
  1236.             // use the first non blank line for short desc
  1237.             for($i = 0; $i < count($desc); $i++)
  1238.             {
  1239.                 if (strlen($desc[$i]) > 0)
  1240.                 {
  1241.                     $this->_pv_periodline = $i;
  1242.                     $i = count($desc);
  1243.                 }
  1244.             }
  1245.         
  1246.             // check to see if we are going to use a blank line to end the shortdesc
  1247.             // this can only be in the first 4 lines
  1248.             if (count($desc) > 4)
  1249.             {
  1250.                 $max = 4;
  1251.             } else {
  1252.                 $max = count($desc);
  1253.             }
  1254.         
  1255.             for($i = $this->_pv_periodline; $i < $max; $i++)
  1256.             {
  1257.                 if (strlen(trim($desc[$i])) == 0)
  1258.                 {
  1259.                     $this->_pv_periodline = $i;
  1260.                     $i = $max;
  1261.                 }
  1262.             }
  1263.         }
  1264.  
  1265.         $dtype = $this->_pv_dtype;
  1266.         if ($dtype == '_pv_docblock')
  1267.         {
  1268.             $sdesc = new parserDesc;
  1269.             $desci = '';
  1270.             for($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++)
  1271.             {
  1272.                 $desci .= $desc[$i]."\n";
  1273.             }
  1274.             $sdesc->add($this->getInlineTags($desci));
  1275.             $this->_pv_periodline++;
  1276.         
  1277.             $my_desc = new parserDesc;
  1278.             if (isset($this->_pv_dtemplate))
  1279.             {
  1280.                 // copy template values if not overridden
  1281.                 if (!$this->_pv_docblock->getExplicitPackage())
  1282.                 {
  1283.                     if ($p = $this->_pv_dtemplate->getKeyword('package'))
  1284.                     {
  1285.                         $this->_pv_docblock->addKeyword('package',$p);
  1286.                         $this->_pv_docblock->setExplicitPackage();
  1287.                     }
  1288.                     if ($p = $this->_pv_dtemplate->getKeyword('category'))
  1289.                     {
  1290.                         $this->_pv_docblock->addKeyword('category',$p);
  1291.                         $this->_pv_docblock->setExplicitCategory();
  1292.                     }
  1293.                     if ($p = $this->_pv_dtemplate->getKeyword('subpackage'))
  1294.                     {
  1295.                         $this->_pv_docblock->addKeyword('subpackage',$p);
  1296.                     }
  1297.                 }
  1298.                 $tags = $this->_pv_dtemplate->listTags();
  1299.                 foreach($tags as $tag)
  1300.                 {
  1301.                     $this->_pv_docblock->addTag($tag);
  1302.                 }
  1303.                 if (!count($this->_pv_docblock->params)) $this->_pv_docblock->params = $this->_pv_dtemplate->params;
  1304.                 $my_desc->add($this->_pv_dtemplate->sdesc);
  1305.                 $my_desc->add($this->_pv_dtemplate->desc);
  1306.             }
  1307. //            echo "i = ".$this->_pv_periodline."; i < " . count($desc) . "\n";
  1308.             $desci = '';
  1309.             for($i = $this->_pv_periodline; $i < count($desc); $i++)
  1310.             {
  1311.                 // the line will not be set if it doesn't start with a *
  1312.                 if (isset($desc[$i]))
  1313.                 $desci .= $desc[$i]."\n";
  1314.             }
  1315.             $my_desc->add($this->getInlineTags($desci));
  1316.         } else
  1317.         { // this is a docblock template
  1318.             $sdesc = new parserDesc;
  1319.             $desci = '';
  1320.             for($i = 0; ($i <= $this->_pv_periodline) && ($i < count($desc)); $i++)
  1321.             {
  1322.                 if (isset($desc[$i]))
  1323.                     $desci .= $desc[$i]."\n";
  1324.             }
  1325.             $sdesc->add($this->getInlineTags($desci));
  1326.             $this->_pv_periodline++;
  1327.         
  1328.             $my_desc = new parserDesc;
  1329.             $desci = '';
  1330.             for($i=$this->_pv_periodline; $i < count($desc); $i++)
  1331.             {
  1332.                 if (isset($desc[$i]))
  1333.                     $desci .= $desc[$i]."\n";
  1334.             }
  1335.             $my_desc->add($this->getInlineTags($desci));
  1336.         }
  1337.         if ($this->_pf_internal)
  1338.         {
  1339.             addError(PDERROR_INTERNAL_NOT_CLOSED);
  1340.             $this->_pf_internal = false;
  1341.         }
  1342.         $this->$dtype->setShortDesc($sdesc);
  1343.         $this->$dtype->setDesc($my_desc);
  1344.         unset($my_desc);
  1345. //            var_dump($this->$dtype);
  1346. //            exit;
  1347.     }
  1348.     
  1349.     /**
  1350.      * Process the tags of a DocBlock
  1351.      * @param array array of lines that contain all @tags
  1352.      */
  1353.     function handleTags($tags)
  1354.     {
  1355.         $newtags = array();
  1356.         $curtag = '';
  1357.         for($i=0;$i < count($tags);$i++)
  1358.         {
  1359.             if (strpos(trim($tags[$i]),'@') === 0) $tags[$i] = ltrim($tags[$i]);
  1360.             if (substr($tags[$i],0,1) == '@' && substr($tags[$i],0,2) != '@ ')
  1361.             { // start a new tag
  1362.                 if (!empty($curtag))
  1363.                 {
  1364.                     $newtags[] = $curtag;
  1365.                 }
  1366.                 $curtag = $tags[$i];
  1367.             } else $curtag .= "\n".$tags[$i];
  1368.         }
  1369.         if (!empty($curtag)) $newtags[] = $curtag;
  1370.         foreach($newtags as $tag)
  1371.         {
  1372.             $x = explode(' ',str_replace("\t",'    ',$tag));
  1373.             $tagname = substr(array_shift($x),1);
  1374.             $restoftag = $x;
  1375.             if (isset($this->tagHandlers[$tagname]))
  1376.             $handle = $this->tagHandlers[$tagname];
  1377.             else
  1378.             $handle = $this->tagHandlers['*'];
  1379.             $this->$handle($tagname,$restoftag);
  1380.         }
  1381.     }
  1382.     
  1383.     /**
  1384.      * Process all inline tags in text, and convert them to their abstract
  1385.      * object representations.
  1386.      * @param string|array complete code to search for inline tags, if an
  1387.      *                     array, it's an array of strings
  1388.      * @return parserStringWithInlineTags
  1389.      */
  1390.     function getInlineTags($value)
  1391.     {
  1392.         if (is_array($value)) $value = join("\n",$value);
  1393.         global $_phpDocumentor_setting;
  1394.         $priv = (isset($_phpDocumentor_setting['parseprivate']) && $_phpDocumentor_setting['parseprivate'] == 'on');
  1395.         $a = new parserStringWithInlineTags();
  1396.         if (!$priv && $this->_pf_internal)
  1397.         {
  1398.             if ($x = strpos($value,'}}'))
  1399.             {
  1400.                 $x = strrpos($value,'}}');
  1401.                 $value = substr($value,$x + 1);
  1402.                 $this->_pf_internal = false;
  1403.             } else $value = '';
  1404.         } elseif ($this->_pf_internal)
  1405.         {
  1406.             if ($x = strpos($value,'}}'))
  1407.             {
  1408.                 $x = strrpos($value,'}}');
  1409.                 $value = substr($value,0,$x) . substr($value,$x+2);
  1410.             }
  1411.         }
  1412.         $save = $value;
  1413.         $value = explode('{@',$value);
  1414.         $newval = array();
  1415.         $a->add($value[0]);
  1416.         for($i=1;$i<count($value);$i++)
  1417.         {
  1418.             if (!$priv && $this->_pf_internal)
  1419.             { // ignore anything between {@internal and }}
  1420.                 if (strpos($value[$i],'}}') !== false)
  1421.                 {
  1422.                     $x = strrpos($value[$i],'}}');
  1423.                     $value[$i] = substr($value[$i],$x + 1);
  1424.                     $this->_pf_internal = false;
  1425.                     if (!$value[$i]) continue;
  1426.                     $a->add($value[$i]);
  1427.                     continue;
  1428.                 } else continue;
  1429.             }
  1430.             if (substr($value[$i],0,1) == '}')
  1431.             {
  1432.                 $a->add('{@'.substr($value[$i],1));
  1433.             } elseif (substr($value[$i],0,2) == '*}')
  1434.             { // used for inserting */ in code examples
  1435.                 $a->add('*/'.substr($value[$i],2));
  1436.             } else
  1437.             {
  1438.                 $save = $value[$i];
  1439.                 $value[$i] = split("[\t ]",str_replace("\t",'    ',$value[$i]));
  1440.                 $word = trim(array_shift($value[$i]));
  1441.                 $val = join(' ',$value[$i]);
  1442.                 if (trim($word) == 'internal')
  1443.                 {
  1444.                     $this->_pf_internal = true;
  1445.                     $value[$i] = substr($save,strlen('internal') + 1);
  1446.                     if (strpos($value[$i],'}}') !== false)
  1447.                     {
  1448.                         $x = strrpos($value[$i],'}}');
  1449.                         // strip internal and cycle as if it were normal text.
  1450.                         $startval = substr($value[$i],0,$x - 1);
  1451.                         if ($priv) $a->add($startval);
  1452.                         $value[$i] = substr($value[$i],$x + 1);
  1453.                         if (!$value[$i]) $value[$i] = '';
  1454.                         $this->_pf_internal = false;
  1455.                         $a->add($value[$i]);
  1456.                         continue;
  1457.                     } elseif ($priv) $a->add($value[$i]);
  1458.                     continue;
  1459.                 }
  1460.                 if (in_array(str_replace('}','',trim($word)),$this->allowableInlineTags))
  1461.                 {
  1462.                     if (strpos($word,'}'))
  1463.                     {
  1464.                         $res = substr($word,strpos($word, '}'));
  1465.                         $word = str_replace('}','',trim($word));
  1466.                         $val = $res.$val;
  1467.                     }
  1468.                     if ($word == 'source')
  1469.                     {
  1470.                         $this->_pf_get_source = true;
  1471.                     }
  1472.                     $val = explode('}',$val);
  1473.                     if (count($val) == 1)
  1474.                     {
  1475.                            addError(PDERROR_UNTERMINATED_INLINE_TAG,$word,'',$save);
  1476.                     }
  1477.                     $rest = $val;
  1478.                     $val = array_shift($rest);
  1479.                     $rest = join('}',$rest);
  1480.                     if (isset($this->inlineTagHandlers[$word]))
  1481.                     $handle = $this->inlineTagHandlers[$word];
  1482.                     else
  1483.                     $handle = $this->inlineTagHandlers['*'];
  1484.                     $val = $this->$handle($word,$val);
  1485.                     $a->add($val);
  1486.                     if ($this->_pf_internal)
  1487.                     {
  1488.                         if (strpos($rest,'}}') !== false)
  1489.                         {
  1490.                             $value[$i] = $rest;
  1491.                             $x = strrpos($value[$i],'}}');
  1492.                             $startval = substr($value[$i],0,$x - 1);
  1493.                             if ($priv) $a->add($startval);
  1494.                             $value[$i] = substr($value[$i],$x + 1);
  1495.                             if (!$value[$i]) $value[$i] = '';
  1496.                             $this->_pf_internal = false;
  1497.                             $a->add($value[$i]);
  1498.                         } else $a->add($rest);
  1499.                     } else $a->add($rest);
  1500.                 } else
  1501.                 {
  1502.                     $val = $word.' '.$val;
  1503.                     $a->add('{@'.$val);
  1504.                 }
  1505.             }
  1506.         }
  1507.         return $a;
  1508.     }
  1509.     /**#@-*/
  1510.     /**#@+
  1511.      * @param string name of the tag
  1512.      * @param string any parameters passed to the inline tag
  1513.      * @access private
  1514.      */
  1515.     /**
  1516.      * Most inline tags require no special processing
  1517.      * 
  1518.      */
  1519.     function handleDefaultInlineTag($name, $value)
  1520.     {
  1521.         $tag = 'parser'.ucfirst($name).'InlineTag';
  1522.         return new $tag($value,$value);
  1523.     }
  1524.     
  1525.     /**
  1526.      * Handle the inline {@}link} tag
  1527.      * @tutorial tags.inlinelink.pkg
  1528.      */
  1529.     function handleLinkInlineTag($name, $value)
  1530.     {
  1531.         // support hyperlinks of any protocol
  1532.         if (is_numeric(strpos($value,'://')) || (strpos(trim($value),'mailto:') === 0))
  1533.         {
  1534.             $value = str_replace('\\,', '###commanana####', $value);
  1535.             if (strpos($value,','))
  1536.             {
  1537.                 $val = new parserLinkInlineTag($value,$value);
  1538.             } elseif (strpos(trim($value),' '))
  1539.             { // if there is more than 1 parameter, the stuff after the space is the hyperlink text
  1540.                 $i1 = strpos(trim($value),' ') + 1;
  1541.                 $link = substr(trim($value),0,$i1 - 1);
  1542.                 $text = substr(trim($value),$i1);
  1543.                 $val = new parserLinkInlineTag($link,$text);
  1544.             } else
  1545.             {
  1546.                 $val = new parserLinkInlineTag($value,$value);
  1547.             }
  1548.         } else
  1549.         {
  1550.             $value = str_replace('\\,', '###commanana####', $value);
  1551.             if (!strpos($value,','))
  1552.             {
  1553.                 $testp = explode('#',$value);
  1554.                 if (count($testp) - 1)
  1555.                     $val = new parserLinkInlineTag($value,$testp[1]);
  1556.                 else
  1557.                     $val = new parserLinkInlineTag($value,$value);
  1558.             } else
  1559.                 $val = new parserLinkInlineTag($value,$value);
  1560.         }
  1561.         return $val;
  1562.     }
  1563.  
  1564.     /**#@-*/
  1565.     /**#@+
  1566.      * @access private
  1567.      * @param string name of tag
  1568.      * @param array all words in the tag that were separated by a space ' '
  1569.      */
  1570.     /**
  1571.      * Most tags only need the value as a string
  1572.      * @uses getInlineTags() all tag handlers check their values for inline tags
  1573.      */
  1574.     function defaultTagHandler($name, $value)
  1575.     {
  1576.         $dtype = $this->_pv_dtype;
  1577.         $this->$dtype->addKeyword($name,$this->getInlineTags(join(' ',$value)));
  1578.     }
  1579.     
  1580.     /**
  1581.      * @tutorial tags.example.pkg
  1582.      * @uses parserDocBlock::addExample()
  1583.      */
  1584.     function exampleTagHandler($name, $value)
  1585.     {
  1586.         $dtype = $this->_pv_dtype;
  1587.         $this->$dtype->addExample($this->getInlineTags(join(' ',$value)), $this->_path);
  1588.     }
  1589.     
  1590.     /**
  1591.      * @tutorial tags.filesource.pkg
  1592.      * @uses phpDocumentorTWordParser::getFileSource() retrieves the source for
  1593.      *       use in the @filesource tag
  1594.      */
  1595.     function filesourceTagHandler($name, $value)
  1596.     {
  1597.         $dtype = $this->_pv_dtype;
  1598.         $this->$dtype->addFileSource($this->_path, $this->_wp->getFileSource());
  1599.     }
  1600.     
  1601.     /**
  1602.      * @tutorial tags.uses.pkg
  1603.      */
  1604.     function usesTagHandler($name, $value)
  1605.     {
  1606.         $dtype = $this->_pv_dtype;
  1607.         $seel = '';
  1608.         while ($seel == '' && count($value))
  1609.         {
  1610.             $seel = array_shift($value);
  1611.         }
  1612.         $this->$dtype->addUses($this->getInlineTags($seel), $this->getInlineTags(join(' ',$value)));
  1613.     }
  1614.     
  1615.     /**
  1616.      * @tutorial tags.author.pkg
  1617.      */
  1618.     function authorTagHandler($name, $value)
  1619.     {
  1620.         $dtype = $this->_pv_dtype;
  1621.         $value = join(' ',$value);
  1622.         if ((strpos($value,'<') !== false) && (strpos($value,'>') !== false))
  1623.         {
  1624.             $email = substr($value,strpos($value,'<') + 1,strpos($value,'>') - strpos($value,'<') - 1);
  1625.             $value = str_replace('<'.$email.'>','<{@link mailto:'.$email.'}>',$value);
  1626.         }
  1627.         $this->$dtype->addKeyword('author',$this->getInlineTags($value));
  1628.     }
  1629.     
  1630.     /**
  1631.      * @tutorial tags.package.pkg
  1632.      */
  1633.     function packageTagHandler($name, $value)
  1634.     {
  1635.         if (count($value) && empty($value[0]))
  1636.         {
  1637.             $found = false;
  1638.             for($i=0;$i<count($value) && !strlen($value[$i]);$i++);
  1639.             array_splice($value,0,$i);
  1640.         }
  1641.         $this->defaultTagHandler($name, $value);
  1642.         $dtype = $this->_pv_dtype;
  1643.         $this->$dtype->setExplicitPackage();
  1644.     }
  1645.     
  1646.     /**
  1647.      * @tutorial tags.category.pkg
  1648.      */
  1649.     function categoryTagHandler($name, $value)
  1650.     {
  1651.         if (count($value) && empty($value[0]))
  1652.         {
  1653.             $found = false;
  1654.             for($i=0;$i<count($value) && !strlen($value[$i]);$i++);
  1655.             array_splice($value,0,$i);
  1656.         }
  1657.         $this->defaultTagHandler($name, $value);
  1658.         $dtype = $this->_pv_dtype;
  1659.         $this->$dtype->setExplicitCategory();
  1660.     }
  1661.     
  1662.     /**
  1663.      * @tutorial tags.global.pkg
  1664.      */
  1665.     function globalTagHandler($name, $value)
  1666.     {
  1667.         $info = $this->retrieveType($value, true);
  1668.         if (!$info) addErrorDie(PDERROR_MALFORMED_TAG, '@global');
  1669.         $type = $info['type'];
  1670.         $var = $info['var'];
  1671.         $desc = $info['desc'];
  1672.         $dtype = $this->_pv_dtype;
  1673.         if (!$var && empty($desc))
  1674.         {
  1675.             if ($type{0} == '$') addError(PDERROR_MALFORMED_GLOBAL_TAG);
  1676.             return $this->$dtype->addFuncGlobal($type,new parserStringWithInlineTags);
  1677.         }
  1678.         if ($var)
  1679.         { // global define
  1680.             $this->_pv_global_type = $type;
  1681.             if (!empty($desc)) $var .= ' '.$desc;
  1682.             $this->findGlobal($var);
  1683.         } elseif (!empty($desc))
  1684.         { // function global
  1685.             if ($type{0} == '$') addError(PDERROR_MALFORMED_GLOBAL_TAG);
  1686.             $this->$dtype->addFuncGlobal($type,$this->getInlineTags($desc));
  1687.         } else
  1688.         {
  1689.             addError(PDERROR_MALFORMED_GLOBAL_TAG);
  1690.         }
  1691.     }
  1692.     
  1693.     /**
  1694.      * @tutorial tags.staticvar.pkg
  1695.      */
  1696.     function staticvarTagHandler($name, $value)
  1697.     {
  1698.         $info = $this->retrieveType($value, true);
  1699.         if (!$info) addErrorDie(PDERROR_MALFORMED_TAG, '@staticvar');
  1700.         $type = $info['type'];
  1701.         $var = $info['var'];
  1702.         $desc = $info['desc'];
  1703.         $dtype = $this->_pv_dtype;
  1704.         if (!$var && empty($desc))
  1705.         {
  1706.             $this->$dtype->addStaticVar(null,$type,new parserStringWithInlineTags);
  1707.         } else
  1708.         {
  1709.             if ($var)
  1710.             {
  1711.                 $this->$dtype->addStaticVar($var,$type,$this->getInlineTags($desc));
  1712.             } else
  1713.             {
  1714.                 $this->$dtype->addStaticVar(null,$type,$this->getInlineTags($desc));
  1715.             }
  1716.         }
  1717.     }
  1718.     
  1719.     /**
  1720.      * @tutorial tags.param.pkg
  1721.      */
  1722.     function paramTagHandler($name, $value)
  1723.     {
  1724.         $info = $this->retrieveType($value, true);
  1725.         //if (!$info) addErrorDie(PDERROR_MALFORMED_TAG, '@param');
  1726.     if (!$info) { addError(PDERROR_MALFORMED_TAG, '@param'); return; }
  1727.         $type = $info['type'];
  1728.         $var = $info['var'];
  1729.         $desc = $info['desc'];
  1730.         $dtype = $this->_pv_dtype;
  1731.         if (!$var && empty($desc))
  1732.         {
  1733.             $this->$dtype->addParam(null,$type,new parserStringWithInlineTags);
  1734.         } else
  1735.         {
  1736.             if ($var)
  1737.             {
  1738.                 $this->$dtype->addParam($var,$type,$this->getInlineTags($desc));
  1739.             } else
  1740.             {
  1741.                 $this->$dtype->addParam(null,$type,$this->getInlineTags($desc));
  1742.             }
  1743.         }
  1744.     }
  1745.     
  1746.     /**
  1747.      * @tutorial tags.return.pkg
  1748.      */
  1749.     function returnTagHandler($name, $value)
  1750.     {
  1751.         $info = $this->retrieveType($value, true);
  1752.         //if (!$info) addErrorDie(PDERROR_MALFORMED_TAG, '@return');
  1753.         if (!$info) { addError(PDERROR_MALFORMED_TAG, '@return'); return; }
  1754.         $type = $info['type'];
  1755.         $desc = $info['desc'];
  1756.         $dtype = $this->_pv_dtype;
  1757.         $this->$dtype->addReturn($type,$this->getInlineTags($desc));
  1758.     }
  1759.     
  1760.     /**
  1761.      * @tutorial tags.var.pkg
  1762.      */
  1763.     function varTagHandler($name, $value)
  1764.     {
  1765.         $info = $this->retrieveType($value, true);
  1766.         if (!$info) addErrorDie(PDERROR_MALFORMED_TAG, '@var');
  1767.         $type = $info['type'];
  1768.         $desc = $info['desc'];
  1769.         $dtype = $this->_pv_dtype;
  1770.         $this->$dtype->addVar($type,$this->getInlineTags($desc));
  1771.     }
  1772.     /**#@-*/
  1773.     /**#@+
  1774.      * @access private
  1775.      */
  1776.     
  1777.     /**
  1778.      * Retrieve the type portion of a @tag type description
  1779.      *
  1780.      * Tags like @param, @return and @var all have a PHP type portion in their
  1781.      * description.  Since the type may contain the expression "object blah"
  1782.      * where blah is a classname, it makes parsing out the type field complex.
  1783.      *
  1784.      * Even more complicated is the case where a tag variable can contain
  1785.      * multiple types, such as object blah|object blah2|false, and so this
  1786.      * method handles these cases.
  1787.      * @param array array of words that were separated by spaces
  1788.      * @param boolean flag to determine whether to check for the end of a
  1789.      *        type is defined by a $varname
  1790.      * @return array Format: array('type' => string, 'var' =>
  1791.      *                             false|string variable name, 'desc' => rest
  1792.      *                             of the tag)
  1793.      */
  1794.     function retrieveType($value, $checkforvar = false)
  1795.     {
  1796.         if (!count($value)) return false;
  1797.         $result = array();
  1798.         $types = '';
  1799.         // remove empty entries resulting from extra spaces between @tag and type
  1800.         $this->_removeWhiteSpace($value, 0);
  1801.         $index = 0;
  1802.         if (trim($value[0]) == 'object')
  1803.         {
  1804.             $types .= array_shift($value).' ';
  1805.             $this->_removeWhiteSpace($value, 0);
  1806.             if (!count($value))
  1807.             { // was just passed "object"
  1808.                 $result = array('type' => rtrim($types),'desc' => '');
  1809.                 if ($checkforvar) $result['var'] = false;
  1810.                 return $result;
  1811.             }
  1812.             if ($value[0]{0} == '$' || substr($value[0],0,2) == '&$')
  1813.             { // was just passed "object" and the next thing is a variable name
  1814.                 $result['var'] = $value[0];
  1815.                 $result['type'] = 'object';
  1816.                 array_shift($value);
  1817.                 $result['desc'] = join(' ', $value);
  1818.                 return $result;
  1819.             }
  1820.         }
  1821.         $done = false;
  1822.         do
  1823.         { // this loop checks for type|type|type and for
  1824.           // type|object classname|type|object classname2
  1825.             if (strpos($value[0], '|'))
  1826.             {
  1827.                 $temptypes = explode('|', $value[0]);
  1828.                 while(count($temptypes))
  1829.                 {
  1830.                     $type = array_shift($temptypes);
  1831.                     $types .= $type;
  1832.                     if (count($temptypes)) $types .= '|';
  1833.                 }
  1834.                 if (trim($type) == 'object')
  1835.                 {
  1836.                     $types .= ' ';
  1837.                     $this->_removeWhiteSpace($value,0);
  1838.                 } else $done = true;
  1839.                 array_shift($value);
  1840.                 if (isset ($value[0]) && strlen($value[0]) && ($value[0]{0} == '$' || substr($value[0],0,2) == '&$'))
  1841.                 { // was just passed "object" and the next thing is a variable name
  1842.                     $result['var'] = $value[0];
  1843.                     $result['type'] = $types;
  1844.                     array_shift($value);
  1845.                     $result['desc'] = join(' ', $value);
  1846.                     return $result;
  1847.                 }
  1848.             } else
  1849.             {
  1850.                 $types .= $value[0];
  1851.                 array_shift($value);
  1852.                 $done = true;
  1853.             }
  1854.         } while (!$done && count($value));
  1855.         $result['type'] = rtrim($types);
  1856.         $this->_removeWhiteSpace($value,0);
  1857.         if ($checkforvar)
  1858.         {
  1859.             if (!count($value))
  1860.             {
  1861.                 $result['var'] = false;
  1862.             } else
  1863.             {
  1864.                 if (substr($value[0],0,1) == '$' || substr($value[0],0,2) == '&$')
  1865.                 {
  1866.                     $result['var'] = $value[0];
  1867.                     array_shift($value);
  1868.                 } else $result['var'] = false;
  1869.             }
  1870.         }
  1871.         $result['desc'] = join(' ',$value);
  1872.         return $result;
  1873.     }
  1874.     
  1875.     /**
  1876.      * @param array array of string
  1877.      * @param integer index to seek non-whitespace to
  1878.      */
  1879.     function _removeWhiteSpace(&$value, $index)
  1880.     {
  1881.         if (count($value) > $index && empty($value[$index]))
  1882.         {
  1883.             $found = false;
  1884.             for($i=$index; $i<count($value) && !strlen($value[$i]); $i++);
  1885.             array_splice($value, $index, $i - $index);
  1886.         }
  1887.     }
  1888.     
  1889.     /**
  1890.      * Retrieve all the tokens that represent the definition of the global
  1891.      * variable.
  1892.      *
  1893.      * {@source}
  1894.      */
  1895.     function findGlobal($name)
  1896.     {
  1897.         $tokens = token_get_all('<?php '.$name);
  1898.         $tokens = array_slice($tokens,1);
  1899.         $this->_wp->findGlobal($tokens);
  1900.         $this->_pv_findglobal = $name;
  1901.     }
  1902.  
  1903.     /**
  1904.      * handler for DEFINE_GLOBAL
  1905.      */
  1906.     function handleGlobal($word, $pevent)
  1907.     {
  1908.         if (isset($this->_pv_findglobal))
  1909.         {
  1910.             $this->_pv_global_name = $this->_pv_findglobal;
  1911.             unset($this->_pv_findglobal);
  1912.         }
  1913.         if (!$this->_pf_in_global)
  1914.         {
  1915.             $this->_pv_linenum = $this->_wp->linenum + 1;
  1916.         }
  1917.         $this->_pf_in_global = true;
  1918.         if($this->checkEventPush($word, $pevent))
  1919.         {
  1920.             $this->_wp->setWhitespace(true);
  1921.         }
  1922.         if ($this->checkEventPop($word, $pevent))
  1923.         {
  1924.             $this->_pf_in_global = false;
  1925.             $a = new parserGlobal;
  1926.             $a->setDataType($this->_pv_global_type);
  1927.             $this->_pv_global_type = '';
  1928.             $a->setLineNumber($this->_pv_linenum);
  1929.             $a->setName($this->_pv_global_name);
  1930.             if (isset($this->_pv_global_val))
  1931.             $a->setValue(trim($this->_pv_global_val));
  1932.             $this->publishEvent(PHPDOCUMENTOR_EVENT_GLOBAL,$a);
  1933.             unset($this->_pv_global_val);
  1934.             unset($this->_pv_global_type);
  1935.         }
  1936.     }
  1937.     
  1938.     /**
  1939.      * handler for GLOBAL_VALUE
  1940.      */
  1941.     function handleGlobalValue($word, $pevent)
  1942.     {
  1943.         if ($this->checkEventPush($word, $pevent)) return;
  1944.         $this->_wp->setWhitespace(true);
  1945.         if (!isset($this->_pv_global_val)) $this->_pv_global_val = '';
  1946.         if ($this->_last_pevent == PARSER_EVENT_ARRAY)
  1947.         {
  1948.             $this->_pv_global_val .= $this->_pv_function_data;
  1949.             $this->_pv_function_data = '';
  1950.         }
  1951.         if ($this->_last_pevent == PARSER_EVENT_QUOTE)
  1952.         {
  1953.             $this->_pv_global_val .= $this->_pv_quote_data;
  1954.             unset($this->_pv_quote_data);
  1955.         }
  1956.         if ($this->checkEventPop($word, $pevent))
  1957.         {
  1958.             $this->_wp->setWhitespace(false);
  1959.             $this->_wp->backupPos();
  1960.             return;
  1961.         }
  1962.         if (is_array($word)) $word = $word[1];
  1963.         $this->_pv_global_val .= $word;
  1964.     }
  1965.     
  1966.     /**#@-*/
  1967.     /**
  1968.      * this function checks whether parameter $word is a token for pushing a new event onto the Event Stack.
  1969.      * @return mixed    returns false, or the event number
  1970.      */
  1971.     
  1972.     function checkEventPush($word,$pevent)
  1973.     {
  1974.         if (is_array($word) && $word[0] == T_STRING) $word = $word[1];
  1975.         if (is_array($word))
  1976.         {
  1977.             $pushEvent = &$this->tokenpushEvent;
  1978.             $word = $word[0];
  1979.         } else
  1980.         {
  1981.             $pushEvent = &$this->wordpushEvent;
  1982.             $word = strtolower($word);
  1983.         }
  1984.         $e = false;
  1985.         if (isset($pushEvent[$pevent]))
  1986.         {
  1987.             if (isset($pushEvent[$pevent][$word]))
  1988.             $e = $pushEvent[$pevent][$word];
  1989.         }
  1990.         if ($e)
  1991.         {
  1992.             $this->_event_stack->pushEvent($e);
  1993.             return $e;
  1994.         } else {
  1995.             return false;
  1996.         }
  1997.     }
  1998.  
  1999.     /**
  2000.      * this function checks whether parameter $word is a token for popping the current event off of the Event Stack.
  2001.      * @return mixed    returns false, or the event number popped off of the stack
  2002.      */
  2003.     
  2004.     function checkEventPop($word,$pevent)
  2005.     {
  2006.         if (is_array($word) && $word[0] == T_STRING) $word = $word[1];
  2007.         if (is_array($word))
  2008.         {
  2009.             $popEvent = &$this->tokenpopEvent;
  2010.             $word = $word[0];
  2011.         } else
  2012.         {
  2013.             $popEvent = &$this->wordpopEvent;
  2014.             $word = strtolower($word);
  2015.         }
  2016.         if (!isset($popEvent[$pevent])) return false;
  2017.         if (in_array($word,$popEvent[$pevent]))
  2018.         {
  2019.             return $this->_event_stack->popEvent();
  2020.         } else {
  2021.             return false;
  2022.         }
  2023.     }
  2024.  
  2025.     function getToken($word)
  2026.     {
  2027.         if (is_array($word)) return $word[0];
  2028.         return false;
  2029.     }
  2030.     
  2031.     /**
  2032.      * setup the parser tokens, and the pushEvent/popEvent arrays
  2033.      * @see $tokens, $pushEvent, $popEvent
  2034.      */
  2035.     
  2036.     function setupStates()
  2037.     {
  2038.         unset($this->_wp);
  2039.         $this->_wp = new phpDocumentorTWordParser;
  2040.         $this->_pv_class = null;
  2041.         $this->_pv_cur_class = null;
  2042.         $this->_pv_define = null;
  2043.         $this->_pv_define_name = null;
  2044.         $this->_pv_define_value = null;
  2045.         $this->_pv_define_params_data = null;
  2046.         $this->_pv_dtype = null;
  2047.         $this->_pv_docblock = null;
  2048.         $this->_pv_dtemplate = null;
  2049.         $this->_pv_func = null;
  2050.         $this->_pv_findglobal = null;
  2051.         $this->_pv_global_name = null;
  2052.         $this->_pv_global_val = null;
  2053.         $this->_pv_globals = null;
  2054.         $this->_pv_global_count = null;
  2055.         $this->_pv_include_params_data = null;
  2056.         $this->_pv_include_name = null;
  2057.         $this->_pv_include_value = null;
  2058.         $this->_pv_linenum = null;
  2059.         $this->_pv_periodline = null;
  2060.         $this->_pv_paren_count = 0;
  2061.         $this->_pv_statics = null;
  2062.         $this->_pv_static_count = null;
  2063.         $this->_pv_static_val = null;
  2064.         $this->_pv_quote_data = null;
  2065.         $this->_pv_function_data = null;
  2066.         $this->_pv_var = null;
  2067.         $this->_pv_varname = null;
  2068.         $this->_pf_definename_isset = false;
  2069.         $this->_pf_includename_isset = false;
  2070.         $this->_pf_get_source = false;
  2071.         $this->_pf_getting_source = false;
  2072.         $this->_pf_in_class = false;
  2073.         $this->_pf_in_define = false;
  2074.         $this->_pf_in_global = false;
  2075.         $this->_pf_in_include = false;
  2076.         $this->_pf_in_var = false;
  2077.         $this->_pf_funcparam_val = false;
  2078.         $this->_pf_quote_active = false;
  2079.         $this->_pf_reset_quote_data = true;
  2080.         $this->_pf_useperiod = false;
  2081.         $this->_pf_var_equals = false;
  2082.         $this->_event_stack = new EventStack;
  2083.     }
  2084.     
  2085.     /**
  2086.      * Creates the state arrays
  2087.      */
  2088.     function setupEventStates()
  2089.     {
  2090.         if (!defined('T_ML_COMMENT'))
  2091.         {
  2092.             define('T_ML_COMMENT', T_DOC_COMMENT);
  2093.         }
  2094. /**************************************************************/
  2095.  
  2096.         $this->wordpushEvent[PARSER_EVENT_LOGICBLOCK] = 
  2097.             array(
  2098.                 "{"    => PARSER_EVENT_LOGICBLOCK,
  2099.                 '"'    => PARSER_EVENT_QUOTE,
  2100.             );
  2101.         $this->tokenpushEvent[PARSER_EVENT_LOGICBLOCK] =
  2102.             array(
  2103.                 T_GLOBAL    => PARSER_EVENT_FUNC_GLOBAL,
  2104.                 T_STATIC    => PARSER_EVENT_STATIC_VAR,
  2105.                 T_CURLY_OPEN    => PARSER_EVENT_LOGICBLOCK,
  2106.                 T_DOLLAR_OPEN_CURLY_BRACES => PARSER_EVENT_LOGICBLOCK,
  2107.             );
  2108.  
  2109.         $this->wordpopEvent[PARSER_EVENT_LOGICBLOCK] = array("}");
  2110.         $this->tokenpopEvent[PARSER_EVENT_LOGICBLOCK] = array(T_CURLY_OPEN);
  2111. /**************************************************************/
  2112.  
  2113.         $this->tokenpushEvent[PARSER_EVENT_NOEVENTS] = 
  2114.             array(
  2115.                 T_OPEN_TAG => PARSER_EVENT_PHPCODE,
  2116.             );
  2117.  
  2118. /**************************************************************/
  2119.  
  2120.         $this->tokenpushEvent[PARSER_EVENT_PHPCODE] = 
  2121.             array(
  2122.                 T_FUNCTION     => PARSER_EVENT_FUNCTION,
  2123.                 T_CLASS     => PARSER_EVENT_CLASS,
  2124.                 T_INCLUDE_ONCE => PARSER_EVENT_INCLUDE,
  2125.                 T_INCLUDE => PARSER_EVENT_INCLUDE,
  2126.                 T_REQUIRE    => PARSER_EVENT_INCLUDE,
  2127.                 T_REQUIRE_ONCE    => PARSER_EVENT_INCLUDE,
  2128.                 T_COMMENT   => PARSER_EVENT_DOCBLOCK,
  2129.                 T_ML_COMMENT         => PARSER_EVENT_DOCBLOCK,
  2130. //                "/**#@+"    => PARSER_EVENT_DOCBLOCK_TEMPLATE,
  2131. //                "/**#@-*/"    => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,
  2132.                 T_CLOSE_TAG         => PARSER_EVENT_OUTPHP,
  2133.             );
  2134.         $this->wordpushEvent[PARSER_EVENT_PHPCODE] =
  2135.             array(
  2136.                 "define"     => PARSER_EVENT_DEFINE,
  2137.             );
  2138. /**************************************************************/
  2139.  
  2140.         $this->tokenpopEvent[PARSER_EVENT_OUTPHP] = array(T_OPEN_TAG);
  2141. /**************************************************************/
  2142.  
  2143.         $this->wordpushEvent[PARSER_EVENT_FUNCTION] =
  2144.             array(
  2145.                 '{'     => PARSER_EVENT_LOGICBLOCK,
  2146.                 '('     => PARSER_EVENT_FUNCTION_PARAMS,
  2147.             );
  2148.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION] =
  2149.             array(
  2150.                 T_COMMENT   => PARSER_EVENT_COMMENT,
  2151.                 T_ML_COMMENT => PARSER_EVENT_COMMENT,
  2152.             );
  2153.  
  2154.         $this->wordpopEvent[PARSER_EVENT_FUNCTION] = array("}");
  2155. /**************************************************************/
  2156.  
  2157.         $this->wordpopEvent[PARSER_EVENT_QUOTE] = array('"');
  2158. /**************************************************************/
  2159.  
  2160.         $this->tokenpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
  2161.             array(
  2162.                 T_CONSTANT_ENCAPSED_STRING => PARSER_EVENT_QUOTE,
  2163.                 T_ARRAY => PARSER_EVENT_ARRAY,
  2164.                 T_COMMENT => PARSER_EVENT_COMMENT,
  2165.                 T_ML_COMMENT => PARSER_EVENT_COMMENT,
  2166.             );
  2167.         $this->wordpushEvent[PARSER_EVENT_FUNCTION_PARAMS] =
  2168.             array(
  2169.                 '"' => PARSER_EVENT_QUOTE,
  2170.                 "'" => PARSER_EVENT_QUOTE,
  2171.             );
  2172.         $this->wordpopEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(")");
  2173. /**************************************************************/
  2174.  
  2175.         $this->tokenpushEvent[PARSER_EVENT_ARRAY] = 
  2176.             array(
  2177.                 T_COMMENT  => PARSER_EVENT_COMMENT,
  2178.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2179.             );
  2180.         $this->wordpopEvent[PARSER_EVENT_ARRAY] = array(")");
  2181. /**************************************************************/
  2182.  
  2183.         $this->tokenpushEvent[PARSER_EVENT_FUNC_GLOBAL] =
  2184.             array(
  2185.                 T_COMMENT   => PARSER_EVENT_COMMENT,
  2186.                 T_ML_COMMENT    => PARSER_EVENT_COMMENT,
  2187.             );
  2188.  
  2189.         $this->wordpopEvent[PARSER_EVENT_FUNC_GLOBAL] = array(";");
  2190. /**************************************************************/
  2191.  
  2192.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR] =
  2193.             array(
  2194.                 T_CONSTANT_ENCAPSED_STRING  => PARSER_EVENT_QUOTE,
  2195.                 T_COMMENT   => PARSER_EVENT_COMMENT,
  2196.                 T_ML_COMMENT    => PARSER_EVENT_COMMENT,
  2197.             );
  2198.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR] =
  2199.             array(
  2200.                 "="        => PARSER_EVENT_STATIC_VAR_VALUE,
  2201.             );
  2202.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR] = array(";");
  2203. /**************************************************************/
  2204.  
  2205.         $this->tokenpushEvent[PARSER_EVENT_STATIC_VAR_VALUE] = 
  2206.             array(
  2207.                 T_CONSTANT_ENCAPSED_STRING  => PARSER_EVENT_QUOTE,
  2208.                 T_COMMENT   => PARSER_EVENT_COMMENT,
  2209.                 T_ML_COMMENT    => PARSER_EVENT_COMMENT,
  2210.                 T_ARRAY     => PARSER_EVENT_ARRAY,
  2211.             );
  2212.         $this->wordpushEvent[PARSER_EVENT_STATIC_VAR_VALUE] =
  2213.             array(
  2214.                 '"' => PARSER_EVENT_QUOTE,
  2215.                 "'" => PARSER_EVENT_QUOTE,
  2216.             );
  2217.         $this->wordpopEvent[PARSER_EVENT_STATIC_VAR_VALUE] = array(";",",");
  2218. /**************************************************************/
  2219.  
  2220.         $this->tokenpushEvent[PARSER_EVENT_DEFINE] = 
  2221.             array(
  2222.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2223.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2224.                 T_CONSTANT_ENCAPSED_STRING        => PARSER_EVENT_QUOTE,
  2225.             );
  2226.         $this->wordpushEvent[PARSER_EVENT_DEFINE] = 
  2227.             array(
  2228.                 "("     => PARSER_EVENT_DEFINE_PARAMS,
  2229.             );
  2230.         $this->wordpopEvent[PARSER_EVENT_DEFINE] = array(";");
  2231. /**************************************************************/
  2232.  
  2233.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE] = 
  2234.             array(
  2235.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2236.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2237.             );
  2238.         $this->wordpushEvent[PARSER_EVENT_INCLUDE] = 
  2239.             array(
  2240.                 "("     => PARSER_EVENT_INCLUDE_PARAMS,
  2241.             );
  2242.         $this->wordpopEvent[PARSER_EVENT_INCLUDE] = array(";");
  2243. /**************************************************************/
  2244.  
  2245.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS] = 
  2246.             array(
  2247.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2248.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2249.             );
  2250.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS] = 
  2251.             array(
  2252.                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2253.                 '"' => PARSER_EVENT_QUOTE,
  2254.                 "'" => PARSER_EVENT_QUOTE,
  2255.             );
  2256.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS] = array(")");
  2257. /**************************************************************/
  2258.  
  2259.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS] = 
  2260.             array(
  2261.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2262.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2263.             );
  2264.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS] = 
  2265.             array(
  2266.                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2267.             );
  2268.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS] = array(")");
  2269. /**************************************************************/
  2270.  
  2271.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =
  2272.             array(
  2273.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2274.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2275.             );
  2276.         $this->wordpushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =
  2277.             array(
  2278.                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,
  2279.                 '"' => PARSER_EVENT_QUOTE,
  2280.                 "'" => PARSER_EVENT_QUOTE,
  2281.             );
  2282.         $this->wordpopEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] = array(")");
  2283. /**************************************************************/
  2284.  
  2285.         $this->tokenpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =
  2286.             array(
  2287.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2288.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2289.             );
  2290.         $this->wordpushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =
  2291.             array(
  2292.                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,
  2293.             );
  2294.         $this->wordpopEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] = array(")");
  2295. /**************************************************************/
  2296.  
  2297.         $this->tokenpushEvent[PARSER_EVENT_VAR] = 
  2298.             array(
  2299.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2300.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2301.                 T_ARRAY     => PARSER_EVENT_ARRAY,
  2302.             );
  2303.         $this->wordpopEvent[PARSER_EVENT_VAR] = array(";");
  2304. /**************************************************************/
  2305.  
  2306.         $this->tokenpushEvent[PARSER_EVENT_CLASS] = 
  2307.             array(
  2308.                 T_FUNCTION     => PARSER_EVENT_FUNCTION,
  2309.                 T_VAR         => PARSER_EVENT_VAR,
  2310.                 T_COMMENT         => PARSER_EVENT_DOCBLOCK,
  2311.                 T_ML_COMMENT         => PARSER_EVENT_DOCBLOCK,
  2312.                 T_CLOSE_TAG        => PARSER_EVENT_OUTPHP,
  2313.             );
  2314.         $this->wordpopEvent[PARSER_EVENT_CLASS] = array("}");
  2315. /**************************************************************/
  2316.  
  2317.         $this->tokenpushEvent[PARSER_EVENT_DEFINE_GLOBAL] = 
  2318.             array(
  2319.                 T_COMMENT => PARSER_EVENT_COMMENT,
  2320.                 T_ML_COMMENT => PARSER_EVENT_COMMENT,
  2321.             );
  2322.         $this->wordpushEvent[PARSER_EVENT_DEFINE_GLOBAL] = 
  2323.             array(
  2324.                 "="    => PARSER_EVENT_GLOBAL_VALUE,
  2325.             );
  2326.         $this->wordpopEvent[PARSER_EVENT_DEFINE_GLOBAL] = array(";");
  2327. /**************************************************************/
  2328.  
  2329.         $this->tokenpushEvent[PARSER_EVENT_GLOBAL_VALUE] = 
  2330.             array(
  2331.                 T_ARRAY => PARSER_EVENT_ARRAY,
  2332.                 T_COMMENT     => PARSER_EVENT_COMMENT,
  2333.                 T_ML_COMMENT     => PARSER_EVENT_COMMENT,
  2334.             );
  2335.         $this->wordpushEvent[PARSER_EVENT_GLOBAL_VALUE] =
  2336.             array(
  2337.                 '"' => PARSER_EVENT_QUOTE,
  2338.                 "'" => PARSER_EVENT_QUOTE,
  2339.             );
  2340.         $this->wordpopEvent[PARSER_EVENT_GLOBAL_VALUE] = array(";");
  2341.     }
  2342.     
  2343.     function configWordParser(&$data)
  2344.     {
  2345.         $this->_wp->setup($data);
  2346.         $this->_wp->setWhitespace(false);
  2347.     }
  2348. }
  2349. ?>
  2350.