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