changed git call from https to git readonly
[atutor.git] / mods / phpdoc2 / PhpDocumentor / phpDocumentor / Parser.inc
1 <?php\r
2 /**\r
3  * Base parser for all parsers\r
4  * \r
5  * phpDocumentor :: automatic documentation generator\r
6  * \r
7  * PHP versions 4 and 5\r
8  *\r
9  * Copyright (c) 2000-2006 Joshua Eichorn, 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  * @package    phpDocumentor\r
29  * @subpackage Parsers\r
30  * @author     Joshua Eichorn <jeichorn@phpdoc.org>\r
31  * @author     Gregory Beaver <cellog@php.net>\r
32  * @copyright  2000-2006 Joshua Eichorn, Gregory Beaver\r
33  * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL\r
34  * @version    CVS: $Id: Parser.inc,v 1.9 2007/06/22 14:58:30 ashnazg Exp $\r
35  * @link       http://www.phpdoc.org\r
36  * @link       http://pear.php.net/PhpDocumentor\r
37  * @since      0.1\r
38  */\r
39 /** used when a backslash is encountered in parsing a string or other escapable entity */ \r
40 define("PARSER_EVENT_ESCAPE"        ,    900);\r
41 /** used when a backslash is encountered in parsing a string or other escapable entity */ \r
42 define("STATE_ESCAPE"            ,    1000);\r
43 \r
44 /** Class published to IntermediateParser with this event */\r
45 define("PHPDOCUMENTOR_EVENT_CLASS"        ,    800);\r
46 /** DocBlock published to IntermediateParser with this event */\r
47 define("PHPDOCUMENTOR_EVENT_DOCBLOCK"        ,    801);\r
48 /** Function published to IntermediateParser with this event */\r
49 define("PHPDOCUMENTOR_EVENT_FUNCTION"        ,    802);\r
50 /** Class Variable published to IntermediateParser with this event */\r
51 define("PHPDOCUMENTOR_EVENT_VAR"        ,    803);\r
52 /** New File (page) published to IntermediateParser with this event */\r
53 define("PHPDOCUMENTOR_EVENT_PAGE"        ,    804);\r
54 /** Constant (define) published to IntermediateParser with this event */\r
55 define("PHPDOCUMENTOR_EVENT_DEFINE"        ,    805);\r
56 /** Class Constant published to IntermediateParser with this event */\r
57 define("PHPDOCUMENTOR_EVENT_CONST"        ,    806);\r
58 /** @deprecated */\r
59 define("PHPDOCUMENTOR_EVENT_MESSAGE"        ,    807);\r
60 /** use to inform IntermediateParser of a new element being parsed */\r
61 define("PHPDOCUMENTOR_EVENT_NEWSTATE"        ,    808);\r
62 /**\r
63  * used to inform phpDocumentor_IntermediateParser that the current file has been completely parsed.\r
64  * Render then flushes all buffers for functions/classes/defines/includes on the current page\r
65  * @see phpDocumentor_IntermediateParser::HandleEvent()\r
66  */\r
67 define("PHPDOCUMENTOR_EVENT_END_PAGE"        ,    808);\r
68 /** Package-level page published to IntermediateParser with this event */\r
69 define("PHPDOCUMENTOR_EVENT_PACKAGEPAGE"        ,    809);\r
70 /** Include (include/require/include_once/include_once) published to IntermediateParser with this event */\r
71 define("PHPDOCUMENTOR_EVENT_INCLUDE"        ,    810);\r
72 /** Tutorial published to IntermediateParser with this event */\r
73 define("PHPDOCUMENTOR_EVENT_TUTORIAL"        ,    811);\r
74 /** Contents of README/INSTALL/CHANGELOG files published to IntermediateParser with this event */\r
75 define("PHPDOCUMENTOR_EVENT_README_INSTALL_CHANGELOG"        ,    812);\r
76 \r
77 /** use to inform ErrorTracker of a new file being parsed */\r
78 define("PHPDOCUMENTOR_EVENT_NEWFILE"    ,    811);\r
79 /** use to inform ErrorTracker of the next line number being parsed */\r
80 define("PHPDOCUMENTOR_EVENT_NEWLINENUM"    ,    812);\r
81 /** used when a global variable definition is encountered in the source */\r
82 define("PHPDOCUMENTOR_EVENT_GLOBAL"    ,    813);\r
83 /** used when a docblock template is encountered in the source */\r
84 define("PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE"    ,    814);\r
85 /** used when a docblock template is encountered in the source */\r
86 define("PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE"    ,    815);\r
87 /** used when double quotation mark (") encountered in parsing */\r
88 define("PARSER_EVENT_QUOTE"        ,    101);\r
89 /** currently parsing a quote */\r
90 define("STATE_QUOTE"            ,    201);\r
91 \r
92 /** { encountered in parsing a function or php code */\r
93 define("PARSER_EVENT_LOGICBLOCK"    ,    102);\r
94 /** currently parsing a { } block */\r
95 define("STATE_LOGICBLOCK"        ,    202);\r
96 \r
97 /** used for the beginning of parsing, before first < ? php encountered */\r
98 define("PARSER_EVENT_NOEVENTS"        ,    103);\r
99 /** out of < ? php tag */\r
100 define("STATE_NOEVENTS"            ,    203);\r
101 \r
102 /** used when long comment /x x/ where x is an asterisk is encountered in parsing */\r
103 define("PARSER_EVENT_COMMENTBLOCK"    ,    104);\r
104 /** currently parsing a long comment /x x/ where x is an asterisk */\r
105 define("STATE_COMMENTBLOCK"        ,    204);\r
106 \r
107 /** used when short comment // is encountered in parsing */\r
108 define("PARSER_EVENT_COMMENT"        ,    105);\r
109 /** currently parsing a short comment // */\r
110 define("STATE_COMMENT"            ,    205);\r
111 \r
112 /** used when php code processor instruction (< ? php) is encountered in parsing */\r
113 define("PARSER_EVENT_PHPCODE"        ,    106);\r
114 /** currently parsing php code */\r
115 define("STATE_PHPCODE"            ,    206);\r
116 \r
117 /** used when a define statement is encountered in parsing */\r
118 define("PARSER_EVENT_DEFINE"        ,    107);\r
119 /** currently parsing a define statement */\r
120 define("STATE_DEFINE"            ,    207);\r
121 \r
122 /** used when a define statement opening parenthesis is encountered in parsing */\r
123 define("PARSER_EVENT_DEFINE_PARAMS"    ,    108);\r
124 /** currently parsing the stuff in ( ) of a define statement */\r
125 define("STATE_DEFINE_PARAMS"        ,    208);\r
126 \r
127 /** used when a function statement opening parenthesis is encountered in parsing */\r
128 define("PARSER_EVENT_FUNCTION_PARAMS"    ,    109);\r
129 /** currently parsing the stuff in ( ) of a function definition */\r
130 define("STATE_FUNCTION_PARAMS"        ,    209);\r
131 \r
132 /** used when a single quote (') is encountered in parsing */\r
133 define("PARSER_EVENT_SINGLEQUOTE"    ,    110);\r
134 /** currently parsing a string enclosed in single quotes (') */\r
135 define("STATE_SINGLEQUOTE"        ,    210);\r
136 \r
137 /** used when a class definition is encountered in parsing */\r
138 define("PARSER_EVENT_CLASS"        ,    111);\r
139 /** currently parsing a class definition */\r
140 define("STATE_CLASS"            ,    211);\r
141 /** used to tell Render that a class has been completely parsed, and to flush buffers */\r
142 define("STATE_END_CLASS"        ,    311);\r
143 \r
144 /** used when a DocBlock is encountered in parsing */\r
145 define("PARSER_EVENT_DOCBLOCK"        ,    112);\r
146 /** currently parsing a DocBlock */\r
147 define("STATE_DOCBLOCK"            ,    212);\r
148 \r
149 /** used when a @tag is encountered in DocBlock parsing */\r
150 define("PARSER_EVENT_DOCKEYWORD"    ,    113);\r
151 /** currently parsing a @tag in a DocBlock */\r
152 define("STATE_DOCKEYWORD"        ,    213);\r
153 \r
154 /** used when a <email@address> is encountered in parsing an @author tag*/\r
155 define("PARSER_EVENT_DOCKEYWORD_EMAIL"    ,    114);\r
156 /** currently parsing an email in brackets in an @author tag of a DocBlock */\r
157 define("STATE_DOCKEYWORD_EMAIL"        ,    214);\r
158 \r
159 /** used when an array definition is encountered in parsing */\r
160 define("PARSER_EVENT_ARRAY"        ,    115);\r
161 /** currently parsing an array */\r
162 define("STATE_ARRAY"            ,    215);\r
163 \r
164 /** used when a var statement is encountered in parsing a class definition */\r
165 define("PARSER_EVENT_VAR"        ,    116);\r
166 /** currently parsing a Class variable */\r
167 define("STATE_VAR"            ,    216);\r
168 \r
169 /** used when a function definition is encountered in parsing */\r
170 define("PARSER_EVENT_FUNCTION"        ,    117);\r
171 /** currently parsing a Function or Method */\r
172 define("STATE_FUNCTION"            ,    217);\r
173 \r
174 /** used when a ? > (with no space) is encountered in parsing */\r
175 define("PARSER_EVENT_OUTPHP"        ,    118);\r
176 /** currently out of php code */\r
177 define("STATE_OUTPHP"            ,    218);\r
178 \r
179 /** used when an inline {@tag} is encountered in parsing a DocBlock */\r
180 define("PARSER_EVENT_INLINE_DOCKEYWORD"    ,    119);\r
181 /** currently parsing an inline tag like { @link} in a DocBlock */\r
182 define("STATE_INLINE_DOCKEYWORD"        ,    219);\r
183 \r
184 /** used when a define statement's opening parenthesis is encountered in parsing */\r
185 define("PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS"    ,    120);\r
186 /** currently parsing an inner parenthetical statement of a define( ) */\r
187 define("STATE_DEFINE_PARAMS_PARENTHESIS"        ,    220);\r
188 \r
189 define("PARSER_EVENT_END_STATEMENT",    121);\r
190 \r
191 /** used when a <<< is encountered in parsing */\r
192 define("PARSER_EVENT_EOFQUOTE"    ,    122);\r
193 /** currently parsing a string defined using Perl <<< */\r
194 define("STATE_EOFQUOTE"        ,    222);\r
195 \r
196 /** used when an include/require/include_once/include_once statement is encountered in parsing */\r
197 define("PARSER_EVENT_INCLUDE"    ,    123);\r
198 /** currently parsing an include/require/include_once/include_once */\r
199 define("STATE_INCLUDE"    ,    223);\r
200 \r
201 /** used when an opening parenthesis of an include/require/include_once/include_once statement is encountered in parsing */\r
202 define("PARSER_EVENT_INCLUDE_PARAMS"    ,    124);\r
203 /** currently parsing the stuff in ( ) of a define statement */\r
204 define("STATE_INCLUDE_PARAMS"    ,    224);\r
205 \r
206 /** used when an inner ( ) is encountered while parsing an include/require/include_once/include_once statement */\r
207 define("PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS"    ,    125);\r
208 /** currently parsing an inner parenthetical statement of an include/includeonce/require/requireonce( ) */\r
209 define("STATE_INCLUDE_PARAMS_PARENTHESIS"    ,    225);\r
210 \r
211 /** used when parsing the desc part of a docblock */\r
212 define("PARSER_EVENT_DESC"    ,    126);\r
213 /** currently parsing the desc part of a docblock */\r
214 define("STATE_DESC"    ,    226);\r
215 \r
216 /** used when parsing the @tag block of a docblock */\r
217 define("PARSER_EVENT_TAGS"    ,    127);\r
218 /** currently parsing the @tag block of a docblock */\r
219 define("STATE_TAGS"    ,    227);\r
220 \r
221 /** used when parsing a global variable declaration */\r
222 define("PARSER_EVENT_DEFINE_GLOBAL"    ,    128);\r
223 /** currently parsing a global variable declaration */\r
224 define("STATE_GLOBAL"    ,    228);\r
225 \r
226 /** used when parsing the default value in a global variable declaration */\r
227 define("PARSER_EVENT_GLOBAL_VALUE"    ,    129);\r
228 /** currently parsing the default value in a global variable declaration */\r
229 define("STATE_GLOBAL_VALUE"    ,    229);\r
230 \r
231 /** used when parsing a "global $var1, $var2;" declaration in a function */\r
232 define("PARSER_EVENT_FUNC_GLOBAL"    ,    130);\r
233 /** currently parsing a "global $var1, $var2;" declaration in a function */\r
234 define("STATE_FUNC_GLOBAL"    ,    230);\r
235 \r
236 /** used when parsing a "static $var1, $var2;" declaration in a function */\r
237 define("PARSER_EVENT_STATIC_VAR"    ,    131);\r
238 /** currently parsing a "static $var1, $var2;" declaration in a function */\r
239 define("STATE_STATIC_VAR"    ,    231);\r
240 \r
241 /** used when parsing the value in a "static $var1 = x" declaration in a function */\r
242 define("PARSER_EVENT_STATIC_VAR_VALUE"    ,    132);\r
243 /** currently parsing the value in a "static $var1 = x" declaration in a function */\r
244 define("STATE_STATIC_VAR_VALUE"    ,    232);\r
245 \r
246 /** used when encountering a /**#@+ comment marking a new docblock template */\r
247 define("PARSER_EVENT_DOCBLOCK_TEMPLATE"    ,    133);\r
248 /** currently parsing the value in a "static $var1 = x" declaration in a function */\r
249 define("STATE_DOCBLOCK_TEMPLATE"    ,    233);\r
250 \r
251 /** used when encountering a /**#@-* / comment (no space) marking the end of using a docblock template */\r
252 define("PARSER_EVENT_END_DOCBLOCK_TEMPLATE"    ,    134);\r
253 /** currently parsing the value in a "static $var1 = x" declaration in a function */\r
254 define("STATE_END_DOCBLOCK_TEMPLATE"    ,    234);\r
255 \r
256 /** used by the {@link HighlightParser} only, when a method starts */\r
257 define("PARSER_EVENT_METHOD"    ,    135);\r
258 /** currently parsing a method using the {@link HighlightParser} */\r
259 define("STATE_METHOD"    ,    235);\r
260 \r
261 /** used by the {@link HighlightParser} only, when a method body is parsed */\r
262 define("PARSER_EVENT_METHOD_LOGICBLOCK"    ,    136);\r
263 /** currently parsing the method body using the {@link HighlightParser} */\r
264 define("STATE_METHOD_LOGICBLOCK"    ,    236);\r
265 \r
266 /** used by the {@link HighlightParser} only, when ->var or ->function() is encountered in a method */\r
267 define("PARSER_EVENT_CLASS_MEMBER"    ,    137);\r
268 /** currently parsing a class member using the {@link HighlightParser} */\r
269 define("STATE_CLASS_MEMBER"    ,    237);\r
270 \r
271 /** used by the {@link HighlightParser} only, when {$var} is encountered in a string */\r
272 define("PARSER_EVENT_QUOTE_VAR"    ,    138);\r
273 /** currently parsing a {$encapsed_var} using the {@link HighlightParser} */\r
274 define("STATE_QUOTE_VAR"    ,    238);\r
275 \r
276 /** used when parsing an access modifier */\r
277 define("PARSER_EVENT_ACCESS_MODIFIER"    ,    139);\r
278 /** currently parsing an access modifier */\r
279 define("STATE_ACCESS_MODIFIER"    ,    239);\r
280 \r
281 /** used when a class implements interfaces */\r
282 define("PARSER_EVENT_IMPLEMENTS"    ,    140);\r
283 /** currently parsing an implements clause */\r
284 define("STATE_IMPLEMENTS"    ,    240);\r
285 \r
286 /** used when a class implements interfaces */\r
287 define("PARSER_EVENT_CLASS_CONSTANT"    ,    141);\r
288 /** currently parsing a class constant */\r
289 define("STATE_CLASS_CONSTANT"    ,    241);\r
290 \r
291 /** used when a variable value is an array */\r
292 define("PARSER_EVENT_VAR_ARRAY"    ,    142);\r
293 /** currently parsing a variable value is an array */\r
294 define("STATE_VAR_ARRAY"    ,    242);\r
295 \r
296 /** used when a comment is found in a variable array value */\r
297 define("PARSER_EVENT_VAR_ARRAY_COMMENT"    ,    143);\r
298 /** currently parsing a comment in a variable array value */\r
299 define("STATE_VAR_ARRAY_COMMENT"    ,    243);\r
300 \r
301 /** used when a $param is encountered in a function definition */\r
302 define("PARSER_EVENT_FUNCTION_PARAM_VAR", 144);\r
303 /** currently parsing a $param in a function definition */\r
304 define("STATE_FUNCTION_PARAM_VAR", 244);\r
305 \r
306 if (!defined('T_INTERFACE'))\r
307 {\r
308     define('T_INTERFACE', 'foo');\r
309     if (!defined('T_CONST')) {\r
310         define('T_CONST', 'foo');\r
311     }\r
312     define('T_ABSTRACT', 'foo');\r
313     define('T_PRIVATE', 'foo');\r
314     define('T_PUBLIC', 'foo');\r
315     define('T_PROTECTED', 'foo');\r
316     define('T_FINAL', 'foo');\r
317     define('T_IMPLEMENTS', 'foo');\r
318 }\r
319 if (!defined('T_ML_COMMENT'))\r
320 {\r
321     define('T_ML_COMMENT', T_COMMENT);\r
322 }\r
323 if (!defined('T_DOC_COMMENT'))\r
324 {\r
325     define('T_DOC_COMMENT', T_ML_COMMENT);\r
326 }\r
327 /**\r
328  * PHP Parser for PHP 4.2.3-\r
329  *\r
330  * This parser is slower than the tokenizer-based parser, and is deprecated.\r
331  * @author    Joshua Eichorn <jeichorn@phpdoc.org>\r
332  * @author    Gregory Beaver <cellog@php.net>\r
333  * @version    $Id: Parser.inc,v 1.9 2007/06/22 14:58:30 ashnazg Exp $\r
334  * @package     phpDocumentor\r
335  * @subpackage Parsers\r
336  * @deprecated in favor of {@link phpDocumentorTParser}\r
337  */\r
338 class Parser extends Publisher\r
339 {\r
340     /**#@+\r
341      * @access private\r
342      */\r
343     /**\r
344      * Word parser\r
345      * @see WordParser\r
346      */\r
347     var $wp;\r
348     \r
349     /**\r
350      * temporary parser variables\r
351      */\r
352     var $p_vars = array('func' => false, 'function_data' => '', 'quote_data' => '', 'event_stack' => false, 'last_pevent' => 0,\r
353                         'two_words_ago' => '', 'temp_word' => '', 'docblock' => false, 'line' => array(), 'linecount' => 0, 'startword' => '',\r
354                         'periodline' => 0, 'shortdesc' => '', 'docblock_desc' => '', 'class' => false, 'source_location' => '',\r
355                         'define_params_data' => '', 'define' => false, 'define_name' => '', 'define_value' => '', 'var' => false,\r
356                         'oldtoken' => false, 'comment_data' => '', 'function_param' => NULL, 'inline_dockeyword_type' => false,\r
357                         'inline_dockeyword_data' => false, 'dockeyword_type' => false, 'dockeyword_data' =>false, 'param_var' => false,\r
358                         'include_name' => '', 'include_value' => '','include' => false, 'return_type' => '', 'cur_class' => '', 'property_name' => false,\r
359                         'function_data' => false, 'varname' => '', 'returntype' => false, 'vartype' => false, 'paramtype' => false,\r
360                         'tagname' => '', 'find_global' => '', 'global_type' => '', 'paramname' => false, 'statics' => array(),\r
361                         'static_count' => 0, 'static_val' => array(), 'docblock_type' => 'docblock', 'seelement' => false);\r
362     \r
363     /**\r
364      * parser flags, for states that don't warrant a new event (like new line in a docblock)\r
365      */\r
366     var $p_flags = array('docblocknewline' => false, 'docblockintags' => false, 'useperiod' => false,\r
367                         'definename_isset' => false, 'define_parens' => false, 'reset_quote_data' => false,\r
368                         'in_desc' => true, 'in_tag' => false, 'newline' => true, 'tempnewline' => false,\r
369                         'start_docblock' => false, 'includename_isset' => false, 'return_isset' => false,\r
370                         'is_return' => false, 'in_class' => false, 'asterisk' => false, 'var_equals' => false,\r
371                         'arrayinvarname' => false, 'valid_newline' => true, 'startline' => false,\r
372                         'function_global' => false, 'define_global' => false, 'static_value' => false,'funcparam_val' => false,\r
373                         'get_source' => false, 'getting_source' => false);\r
374 \r
375     /**\r
376      * lookup table for event handler methods\r
377      * @see Parser::parse()\r
378      */\r
379     var $eventHandlers = array(\r
380                                 'handleArray' => PARSER_EVENT_ARRAY,\r
381                                 'handleClass' => PARSER_EVENT_CLASS,\r
382                                 'handleComment' => PARSER_EVENT_COMMENT,\r
383                                 'handleDocBlockTemplate' => PARSER_EVENT_DOCBLOCK_TEMPLATE,\r
384                                 'handleEndDocBlockTemplate' => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,\r
385                                 'handleEscape' => PARSER_EVENT_ESCAPE,\r
386                                 'handleLogicBlock' => PARSER_EVENT_LOGICBLOCK,\r
387                                 'defaultHandler' => PARSER_EVENT_NOEVENTS,\r
388 //                                'defaultHandler' => PARSER_EVENT_COMMENTBLOCK, (set in constructor below)\r
389 //                                'defaultHandler' => PARSER_EVENT_OUTPHP,\r
390                                 'handleDefine' => PARSER_EVENT_DEFINE,\r
391                                 'handleDefineParams' => PARSER_EVENT_DEFINE_PARAMS,\r
392                                 'handleDefineParamsParenthesis' => PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,\r
393                                 'handleIncludeParamsParenthesis' => PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,\r
394 //                                'handleDocBlock' => PARSER_EVENT_DOCBLOCK,\r
395                                 'BetterhandleDocBlock' => PARSER_EVENT_DOCBLOCK,\r
396                                 'handleTags' => PARSER_EVENT_TAGS,\r
397                                 'handleDesc' => PARSER_EVENT_DESC,\r
398 //                                'handleDockeyword' => PARSER_EVENT_DOCKEYWORD,\r
399                                 'handleTag' => PARSER_EVENT_DOCKEYWORD,\r
400                                 'handleDockeywordEmail' => PARSER_EVENT_DOCKEYWORD_EMAIL,\r
401                                 'handleEOFQuote' => PARSER_EVENT_EOFQUOTE,\r
402                                 'handleFunction' => PARSER_EVENT_FUNCTION,\r
403                                 'handleFunctionParams' => PARSER_EVENT_FUNCTION_PARAMS,\r
404                                 'handleFuncGlobal' => PARSER_EVENT_FUNC_GLOBAL,\r
405                                 'handleGlobal' => PARSER_EVENT_DEFINE_GLOBAL,\r
406                                 'handleGlobalValue' => PARSER_EVENT_GLOBAL_VALUE,\r
407                                 'handleInlineDockeyword' => PARSER_EVENT_INLINE_DOCKEYWORD,\r
408                                 'handleInclude' => PARSER_EVENT_INCLUDE,\r
409                                 'handleIncludeParams' => PARSER_EVENT_INCLUDE_PARAMS,\r
410                                 'handleQuote' => PARSER_EVENT_QUOTE,\r
411                                 'handlePhpCode' => PARSER_EVENT_PHPCODE,\r
412                                 'handleSingleQuote' => PARSER_EVENT_SINGLEQUOTE,\r
413                                 'handleStaticVar' => PARSER_EVENT_STATIC_VAR,\r
414                                 'handleStaticValue' => PARSER_EVENT_STATIC_VAR_VALUE,\r
415                                 'handleVar' => PARSER_EVENT_VAR,\r
416     );\r
417     \r
418     /**\r
419      * event handlers for @tags\r
420      * @tutorial tags.pkg\r
421      */\r
422     var $tagHandlers = array(\r
423                                 '*' => 'defaultTagHandler',\r
424                                 'category' => 'categoryTagHandler',\r
425                                 'example' => 'exampleTagHandler',\r
426                                 'filesource' => 'invalidTagHandler',\r
427                                 'return' => 'returnTagHandler',\r
428                                 'returns' => 'returnTagHandler',\r
429                                 'var' => 'varTagHandler',\r
430                                 'package' => 'packageTagHandler',\r
431                                 'param' => 'paramTagHandler',\r
432                                 'parameter' => 'paramTagHandler',\r
433                                 'global' => 'globalTagHandler',\r
434                                 'staticvar' => 'staticvarTagHandler',\r
435                                 'uses' => 'usesTagHandler',\r
436                                 'property' => 'propertyTagHandler',\r
437                                 'property-read' => 'propertyTagHandler',\r
438                                 'property-write' => 'propertyTagHandler',\r
439                                 'method' => 'propertyTagHandler'\r
440                             );\r
441 \r
442     var $laststart = false;\r
443 \r
444     /**\r
445      * An array of allowable @tags\r
446      */\r
447     var $allowableTags;\r
448 \r
449 \r
450     /**\r
451      * An array of allowed inline @tags\r
452      */\r
453     var $allowableInlineTags;\r
454     \r
455     /**\r
456      * Sets the states up, and creates a new WordParser\r
457      */\r
458     \r
459     /**\r
460      * an array of parsing tokens organized by event number.\r
461      * A token is defined as the smallest group of characters that separates or\r
462      * defines a new parser element.  In English, a space or punctuation are\r
463      * tokens that separate words.  in PHP, tokens may be //, or even "\r
464      * Format: array(eventnum =>array(token1, token2, token3, ...),...)\r
465      * @var array\r
466      */\r
467     var $tokens;\r
468     \r
469     /**\r
470      * array of events that are raised, organized by the tokens that raise them.\r
471      * Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)\r
472      * @var array\r
473      */\r
474     var $pushEvent;\r
475     \r
476     /**\r
477      * array of tokens that end an event, organized by event\r
478      * Format: array(eventnum => array(token => neweventnum, token2 => neweventnum2,...),...)\r
479      * @var array\r
480      */\r
481     var $popEvent;\r
482     /**#@-*/\r
483     \r
484     /**\r
485      * Set up invariant parsing variables\r
486      */\r
487     function Parser()\r
488     {\r
489         $this->allowableTags = $GLOBALS['_phpDocumentor_tags_allowed'];\r
490         $this->allowableInlineTags = $GLOBALS['_phpDocumentor_inline_doc_tags_allowed'];\r
491         $this->wp = new WordParser;\r
492         // strange PHP 4.0.6 behavior: it converts constants to strings without warning if it's an array index\r
493         $this->eventHandlers = array_flip($this->eventHandlers);\r
494         $this->eventHandlers[PARSER_EVENT_COMMENTBLOCK] = 'defaultHandler';\r
495         $this->eventHandlers[PARSER_EVENT_OUTPHP] = 'defaultHandler';\r
496         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWLINENUM,$GLOBALS['phpDocumentor_errors']);\r
497         $this->subscribe(PHPDOCUMENTOR_EVENT_NEWFILE,$GLOBALS['phpDocumentor_errors']);\r
498     }\r
499 \r
500     /**\r
501      * Parse a new file\r
502      *\r
503      * @param    string    $parse_data\r
504      * @param    string    $path\r
505      * @param    int    $base    number of directories to drop off the bottom when creating names using path\r
506      * @staticvar    integer    used for recursion limiting if a handler for an event is not found\r
507      * @return    bool\r
508      */\r
509     function parse (&$parse_data, $path, $base = 0, $packages = false)\r
510     {\r
511         global $_phpDocumentor_options;\r
512         static $endrecur = 0;\r
513         $this->p_vars = array('func' => false, 'function_data' => '', 'quote_data' => '', 'event_stack' => false, 'last_pevent' => 0,\r
514                         'two_words_ago' => '', 'temp_word' => '', 'docblock' => false, 'line' => array(), 'linecount' => 0, 'startword' => '',\r
515                         'periodline' => 0, 'shortdesc' => '', 'docblock_desc' => '', 'class' => false, 'source_location' => '',\r
516                         'define_params_data' => '', 'define' => false, 'define_name' => '', 'define_value' => '', 'var' => false,\r
517                         'oldtoken' => false, 'comment_data' => '', 'function_param' => NULL, 'inline_dockeyword_type' => false,\r
518                         'inline_dockeyword_data' => false, 'dockeyword_type' => false, 'dockeyword_data' =>false, 'param_var' => false,\r
519                         'include_name' => '', 'include_value' => '','include' => false, 'return_type' => '', 'cur_class' => '', 'property_name' => false,\r
520                         'function_data' => false, 'varname' => '', 'returntype' => false, 'vartype' => false, 'paramtype' => false,\r
521                         'tagname' => '', 'find_global' => '', 'global_type' => '', 'paramname' => false, 'statics' => array(),\r
522                         'static_count' => 0, 'static_val' => array(), 'docblock_type' => 'docblock', 'linenum' => false,\r
523                         'seelement' => false);\r
524     \r
525         $this->p_flags = array('docblocknewline' => false, 'docblockintags' => false, 'useperiod' => false,\r
526                         'definename_isset' => false, 'define_parens' => false, 'reset_quote_data' => false,\r
527                         'in_desc' => true, 'in_tag' => false, 'newline' => true, 'tempnewline' => false,\r
528                         'start_docblock' => false, 'includename_isset' => false, 'return_isset' => false,\r
529                         'is_return' => false, 'in_class' => false, 'asterisk' => false, 'var_equals' => false,\r
530                         'arrayinvarname' => false, 'valid_newline' => true, 'startline' => false,\r
531                         'function_global' => false, 'define_global' => false, 'static_value' => false,'funcparam_val' => false,\r
532                         'get_source' => false, 'getting_source' => false, 'in_define' => false, 'in_include' => false,\r
533                         'in_var' => false, 'in_global' => false);\r
534         $this->p_vars['parsepath'] = $path;\r
535         $this->setupStates();\r
536         if (strlen($parse_data) == 0)\r
537         {\r
538             return false;\r
539         }\r
540 \r
541         // initialize variables so E_ALL error_reporting doesn't complain\r
542         $pevent = 0;\r
543         $word = 0;\r
544         $this->p_vars['event_stack'] = new EventStack;\r
545 \r
546         $this->wp->setup($parse_data);\r
547         \r
548 \r
549         $page = new ParserPage;\r
550         $page->setPath($path);\r
551         $page->setPackageOutput($packages);\r
552         $page->setFile(basename($path));\r
553         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWFILE,basename($path));\r
554         //$name = str_replace("/","_",dirname($path)) . "_" . array_shift(explode(".",$page->getFile()));\r
555         // fc@fc.clever-soft.com 11/29/2001\r
556         $name = str_replace( ':', '', dirname($path) . PATH_DELIMITER . $page->getFile() );\r
557         $tmp = explode( PATH_DELIMITER, $name );\r
558         $name = implode( "---", array_slice( $tmp, $base ) );\r
559         // if base is '', drive letter is present in windows\r
560 \r
561         $page->setName($name);\r
562         $temploc = $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER. implode(PATH_DELIMITER,\r
563             array_slice(explode(PATH_DELIMITER,$path),$base));\r
564         \r
565         if ($temploc == $_phpDocumentor_options['Program_Root'] . PATH_DELIMITER) $temploc .= $path;\r
566         \r
567         $this->p_vars['source_location'] = $source_location = $temploc;\r
568         $page->setSourceLocation($source_location);\r
569 \r
570         $this->publishEvent(PHPDOCUMENTOR_EVENT_PAGE,$page);\r
571         unset($page);\r
572         $this->p_flags['reset_quote_data'] = true;\r
573 \r
574         do\r
575         {\r
576             $lpevent = $pevent;\r
577             $pevent = $this->p_vars['event_stack']->getEvent();\r
578             if ($lpevent != $pevent)\r
579             {\r
580                 $this->p_vars['last_pevent'] = $lpevent;\r
581             }\r
582 \r
583             if ($this->p_vars['last_pevent'] != $pevent)\r
584             {\r
585                 // its a new event so the word parser needs to be reconfigured \r
586                 $this->configWordParser($pevent);\r
587             }\r
588         \r
589             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent + 100));\r
590 \r
591             if ($pevent == PARSER_EVENT_GLOBAL_VALUE || $pevent == PARSER_EVENT_DOCBLOCK || $pevent == PARSER_EVENT_DOCBLOCK_TEMPLATE)\r
592             {\r
593                 $this->wp->setWhitespace(true);\r
594             }\r
595 \r
596             $this->p_vars['last_word'] = $word;\r
597             $word = $this->wp->getWord();\r
598             // in wordparser, have to keep track of lines\r
599             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWLINENUM, $this->wp->linenum);\r
600 \r
601             if (PHPDOCUMENTOR_DEBUG == true)\r
602             {\r
603                 echo "\nLAST: |" . $this->p_vars['last_word'] . "|\n";\r
604                 echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";\r
605                 echo "LASTPEVENT: " . $this->getParserEventName($this->p_vars['last_pevent']) . "\n";\r
606                 echo $this->wp->getPos() . ": |$word|\n--------------------------\n\n";\r
607             }\r
608             if ($this->p_flags['get_source'])\r
609             {\r
610                 if ($pevent == PARSER_EVENT_FUNCTION)\r
611                 {\r
612                     $this->wp->retrievesource("function $word");\r
613                     $this->p_flags['get_source'] = false;\r
614                     $this->p_flags['getting_source'] = true;\r
615                 }\r
616             }\r
617             if (false)//$this->p_flags['getting_source'] && ($pevent == PARSER_EVENT_DOCBLOCK) || ($pevent == PARSER_EVENT_NOEVENTS))\r
618             {\r
619                 addError(PDERROR_SOURCE_TAG_FUNCTION_NOT_FOUND);\r
620                 // throw away source\r
621                 $this->wp->getSource();\r
622             }\r
623             if (isset($this->eventHandlers[$pevent]))\r
624             {\r
625                 $handle = $this->eventHandlers[$pevent];\r
626                 $this->$handle($word, $pevent);\r
627             } else\r
628             {\r
629                 debug('WARNING: possible error, no handler for event number '.$pevent);\r
630                 if ($endrecur++ == 25)\r
631                 {\r
632                     die("FATAL ERROR, recursion limit reached");\r
633                 }\r
634             }\r
635         } while (!($word === false));\r
636         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_PAGE);\r
637     }\r
638     \r
639     /**#@+\r
640      * @access private\r
641      * @param string token parsed from source\r
642      * @param integer parser constant from {@link Parser.inc}\r
643      */\r
644     /**\r
645      * handler for NOEVENTS, OUTPHP, COMMENTBLOCK\r
646      */\r
647     \r
648     function defaultHandler($word, $pevent)\r
649     {\r
650         $this->checkEventPush( $word, $pevent);\r
651         $this->checkEventPop($word,$pevent);\r
652     }\r
653     \r
654     /**\r
655      * handler for LOGICBLOCK\r
656      *\r
657      * Logic Blocks are the stuff between { and } in a function/method.  A\r
658      * logic block can clearly contain other logic blocks, as in:\r
659      *\r
660      * <code>\r
661      * function test($a)\r
662      * {\r
663      *    if (testcondition)\r
664      *    { // nested logic block\r
665      *    }\r
666      * }\r
667      * </code>\r
668      *\r
669      * So, the exit portion of the logic block handler must check to see if the\r
670      * logic block being exited is the top-level, and it does this by retrieving\r
671      * the last event from the stack.  If it is a function (and not a logic block)\r
672      * then it backs up the word parser so that the function will exit properly.\r
673      *\r
674      * {@source 11}\r
675      */\r
676     \r
677     function handleLogicBlock($word, $pevent)\r
678     {\r
679         $a = $this->checkEventPush( $word, $pevent);\r
680         if ($a == PARSER_EVENT_FUNC_GLOBAL || $a == PARSER_EVENT_STATIC_VAR)\r
681         {\r
682             if (substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != ' ' && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "\t" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "\n" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != ";" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "}" && substr($this->p_vars['last_word'],strlen($this->p_vars['last_word']) - 1,1) != "{")\r
683             {\r
684                 $this->p_vars['event_stack']->popEvent();\r
685             }\r
686         }\r
687         if ($this->checkEventPop($word,$pevent))\r
688         {\r
689             $e = $this->p_vars['event_stack']->popEvent();\r
690             $this->p_vars['event_stack']->pushEvent($e);\r
691             if ($e == PARSER_EVENT_FUNCTION)\r
692             {\r
693                 $this->wp->backupPos($word); \r
694             }\r
695         }\r
696     }\r
697     \r
698     /**\r
699      * handler for ESCAPE.\r
700      * this event handler parses <code>"this string \"with its escape backslashes\""</code> and returns:\r
701      * <code>this string "with its escape backslashes"</code>\r
702      * to make it human-readable\r
703      */\r
704     \r
705     function handleEscape($word, $pevent)\r
706     {\r
707         $this->p_vars['event_stack']->popEvent();\r
708     }\r
709     \r
710     /**\r
711      * handler for COMMENT.\r
712      * this event handler parses single-line comments like:\r
713      * // this one\r
714      */\r
715     \r
716     function handleComment($word, $pevent)\r
717     {\r
718         $this->checkEventPush( $word, $pevent);\r
719     \r
720         if (!isset($this->p_vars['comment_data'])) $this->p_vars['comment_data'] = '';\r
721         $this->p_vars['comment_data'] .= $word;\r
722     \r
723         $this->checkEventPop($word,$pevent);\r
724     }\r
725 \r
726     /**\r
727      * handler for ARRAY.\r
728      * this event handler parses arrays in default values of function and var definitions\r
729      */\r
730     \r
731     function handleArray($word, $pevent)\r
732     {\r
733         $e = $this->checkEventPush( $word, $pevent); \r
734         if (($e == PARSER_EVENT_COMMENTBLOCK) ||\r
735             ($e == PARSER_EVENT_COMMENT)) return;\r
736 \r
737         if (!isset($this->p_vars['function_data']) || (isset($this->p_vars['function_data']) && empty($this->p_vars['function_data'])))\r
738         {\r
739             $this->p_vars['function_data'] = "array";\r
740         }\r
741 \r
742         if ( ($this->p_vars['last_word'] == "'"))\r
743         {\r
744             $this->p_vars['function_data'] .= $this->p_vars['quote_data']."'";\r
745         }\r
746         if ( ($this->p_vars['last_word'] == "\""))\r
747         {\r
748             $this->p_vars['function_data'] .= $this->p_vars['quote_data']."\"";\r
749         }\r
750 \r
751         $this->p_vars['function_data'] .= $word;\r
752         //echo "function_data = |$this->p_vars['function_data']|\n";\r
753 \r
754         if ($this->checkEventPop($word,$pevent))\r
755         {\r
756         }\r
757     }\r
758 \r
759     /**\r
760      * handler for DEFINE.\r
761      * handles define(constant, value); statements\r
762      */\r
763     \r
764     function handleDefine($word, $pevent)\r
765     {\r
766         if (!$this->p_flags['in_define'])\r
767         {\r
768             $this->p_vars['linenum'] = $this->wp->linenum;\r
769         }\r
770         $this->p_flags['in_define'] = true;\r
771         $this->checkEventPush( $word, $pevent);\r
772 \r
773         $this->p_flags['definename_isset'] = false;\r
774         $this->p_vars['define_params_data'] = '';\r
775         unset($this->p_vars['quote_data']);\r
776         if ($this->checkEventPop($word,$pevent))\r
777         {\r
778             $this->p_flags['in_define'] = false;\r
779             $this->p_vars['define'] = new parserDefine;\r
780             $this->p_vars['define']->setLineNumber($this->p_vars['linenum']);\r
781             $this->p_vars['define']->setName($this->p_vars['define_name']);\r
782             $this->p_vars['define']->setValue($this->p_vars['define_value']);\r
783             $this->publishEvent(PHPDOCUMENTOR_EVENT_DEFINE,$this->p_vars['define']);\r
784             $this->p_flags['definename_isset'] = false;\r
785             unset($this->p_vars['define']);\r
786             unset($this->p_vars['define_name']);\r
787             unset($this->p_vars['define_value']);\r
788             $this->p_flags['in_define'] = false;\r
789             $this->p_vars['define_params_data'] = '';\r
790         }\r
791     }\r
792     \r
793     /**\r
794      * handler for DEFINE_PARAMS.\r
795      * handles the parsing of constant and value in define(constant, value);\r
796      */\r
797     \r
798     function handleDefineParams($word, $pevent)\r
799     {\r
800         if ($this->checkEventPush( $word, $pevent))\r
801         {\r
802             if ($word == '(')\r
803             {\r
804                 $this->p_vars['define_params_data'] .= $word;\r
805             }\r
806             return;\r
807         }\r
808         \r
809         $this->p_flags['define_parens'] = true;\r
810         if(!isset($this->p_vars['define_params_data'])) $this->p_vars['define_params_data'] = '';\r
811         \r
812         if ($this->checkEventPop($word,$pevent))\r
813         {\r
814             if (!empty($this->p_vars['quote_data']))\r
815             {\r
816                 $this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];\r
817             }\r
818             if (!empty($this->p_vars['define_params_data']))\r
819             {\r
820                 //echo $this->p_vars['define_params_data']."\n";\r
821                 $this->p_vars['define_value'] = $this->p_vars['define_params_data'];\r
822             }\r
823             else\r
824             {\r
825                 if (    $this->p_vars['last_word'] != "/*" && \r
826                     $this->p_vars['last_word'] != "//" && $this->p_vars['last_word'] != "#")\r
827                 {\r
828                     $this->p_vars['define_value'] = trim($this->p_vars['last_word']);\r
829                 }\r
830                 else\r
831                 {\r
832                     $this->p_vars['define_value'] = "";\r
833                 }\r
834             }\r
835         }\r
836         if ($this->p_flags['definename_isset'])\r
837         {\r
838             if (isset($this->p_vars['quote_data']))\r
839             {\r
840                 $this->p_vars['define_params_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
841                 unset($this->p_vars['quote_data']);\r
842             }\r
843             $this->p_vars['define_params_data'] .= $word;\r
844         } else\r
845         {\r
846             if ($word != ",")\r
847             {\r
848                 if (isset($this->p_vars['quote_data']))\r
849                 {\r
850                     $this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];\r
851                     unset($this->p_vars['quote_data']);\r
852                 }\r
853                 $this->p_vars['define_params_data'] .= $word;\r
854             } else\r
855             {\r
856                 if (isset($this->p_vars['quote_data']) && !$this->p_flags['definename_isset'])\r
857                 {\r
858                     $this->p_vars['define_params_data'] .= $this->p_vars['quote_data'];\r
859                     unset($this->p_vars['quote_data']);\r
860                 }\r
861                 $this->p_flags['definename_isset'] = true;\r
862                 $this->p_vars['define_name'] = $this->p_vars['define_params_data'];\r
863                 unset($this->p_vars['quote_data']);\r
864                 $this->p_vars['define_params_data'] = '';\r
865             }\r
866         }\r
867     }\r
868     \r
869     /**\r
870      * handler for DEFINE_PARAMS_PARENTHESIS.\r
871      * this handler takes all parenthetical statements within constant or value in:\r
872      * define(constant, value) of a define statement, and handles them properly\r
873      */\r
874     \r
875     function handleDefineParamsParenthesis($word, $pevent)\r
876     {\r
877         if (isset($this->p_vars['quote_data']))\r
878         {\r
879             $this->p_vars['define_params_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
880             unset($this->p_vars['quote_data']);\r
881         }\r
882         $this->p_vars['define_params_data'] .= $word;\r
883         $this->checkEventPush( $word, $pevent);\r
884         $this->checkEventPop( $word, $pevent);\r
885     }\r
886 \r
887     /**\r
888      * handler for CLASS.\r
889      * this handler parses a class statement\r
890      */\r
891     \r
892     function handleClass($word, $pevent)\r
893     {\r
894         $this->p_flags['in_class'] = true;\r
895         $a = $this->checkEventPush( $word, $pevent);\r
896         if ($a == PARSER_EVENT_DOCBLOCK || $a == PARSER_EVENT_DOCBLOCK_TEMPLATE)\r
897         {\r
898             $this->wp->setWhitespace(true);\r
899         }\r
900 \r
901         if (!isset($this->p_vars['class'])) $this->p_vars['class'] = false;\r
902         if (!is_subclass_of($this->p_vars['class'],"parserBase"))\r
903         {\r
904             $this->p_vars['class'] = new parserClass;\r
905             $this->p_vars['class']->setLineNumber($this->wp->linenum);\r
906             $this->p_vars['class']->setname($word);\r
907             $this->p_vars['cur_class'] = $word;\r
908             $this->p_vars['class']->setSourceLocation($this->p_vars['source_location']);\r
909         }\r
910 \r
911         if (strtolower($this->p_vars['last_word']) == "extends")\r
912         {\r
913             $this->p_vars['class']->setExtends($word);\r
914         }\r
915 \r
916         if ($word == "{")\r
917         {\r
918             $this->publishEvent(PHPDOCUMENTOR_EVENT_CLASS,$this->p_vars['class']);\r
919         }\r
920         //echo $this->wp->getPos() . ": |$word|\n";\r
921         if ($this->checkEventPop($word,$pevent))\r
922         {\r
923             $this->p_flags['in_class'] = false;\r
924             // throw an event when class is done\r
925             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,STATE_END_CLASS);\r
926             $this->p_vars['class'] = false;\r
927         }\r
928     }\r
929 \r
930     /**\r
931      * handler for VAR.\r
932      * handle a var $varname = default_value; or var $varname; statement in a class definition\r
933      */\r
934     \r
935     function handleVar($word, $pevent)\r
936     {\r
937         if (!$this->p_flags['in_var'])\r
938         {\r
939             $this->p_vars['linenum'] = $this->wp->linenum;\r
940         }\r
941         $this->p_flags['in_var'] = true;\r
942         //echo $word."\n";\r
943         $e = $this->checkEventPush( $word, $pevent);\r
944         \r
945         if (!isset($this->p_vars['var'])) $this->p_vars['var'] = false;\r
946         if ($word == '=' || $word == ';') $this->p_flags['var_equals'] = true;\r
947         if (!$this->p_flags['var_equals'])\r
948         {\r
949             // if we haven't parsed the = yet, no arrays are possible!\r
950             if ($e == PARSER_EVENT_ARRAY)\r
951             {\r
952                 $this->p_flags['arrayinvarname'] = true;\r
953                 $this->p_vars['event_stack']->popEvent();\r
954             }\r
955             if (!$e || ($e == PARSER_EVENT_ARRAY))\r
956             $this->p_vars['varname'] .= $word;\r
957         }\r
958 \r
959         if (!$this->p_flags['var_equals'])\r
960         {\r
961             if ($word != "/*" && $word != "//" && $word != "#")\r
962             {\r
963                 $this->p_vars['var'] = new parserVar($this->p_vars['cur_class']);\r
964                 $this->p_vars['var']->setName($this->p_vars['varname']);\r
965             }\r
966         }\r
967         if ($this->p_vars['last_word'] == "=")\r
968         {\r
969             if ($word != "/*" && $word != "//" && $word != "#")\r
970             {\r
971                 $this->p_vars['var']->setValue($word);\r
972             }\r
973         }\r
974         // fix 1202772\r
975         if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))\r
976         {\r
977             $this->p_vars['var']->setValue($this->p_vars['quote_data']);\r
978             unset($this->p_vars['quote_data']);\r
979         }\r
980         if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)\r
981         {\r
982             $this->p_vars['var']->setValue($this->p_vars['function_data']);\r
983             $this->p_vars['function_data'] = false;\r
984         }\r
985             \r
986         if ($this->checkEventPop($word,$pevent))\r
987         {\r
988             $this->p_vars['var']->setLineNumber($this->p_vars['linenum']);\r
989             $this->publishEvent(PHPDOCUMENTOR_EVENT_VAR,$this->p_vars['var']);\r
990             unset($this->p_vars['var']);\r
991             $this->p_flags['in_var'] = false;\r
992             $this->p_flags['var_equals'] = false;\r
993             $this->p_flags['arrayinvarname'] = false;\r
994             $this->p_vars['varname'] = '';\r
995         }\r
996     }\r
997 \r
998     /**\r
999      * handler for QUOTE.\r
1000      * this handler recognizes strings defined with double quotation marks (") and handles them correctly\r
1001      * in any place that they legally appear in php code\r
1002      */\r
1003     \r
1004     function handleQuote($word, $pevent)\r
1005     {\r
1006         if ($this->p_flags['reset_quote_data'] === true)\r
1007         {\r
1008             $this->p_flags['reset_quote_data'] = false;\r
1009             $this->p_vars['quote_data'] = "";\r
1010         }\r
1011         $this->checkEventPush( $word, $pevent);\r
1012         if ($word != "\"")\r
1013         {\r
1014             $this->p_vars['quote_data'] .= $word;\r
1015         }\r
1016         if ($this->checkEventPop($word,$pevent))\r
1017         {\r
1018             $this->p_flags['reset_quote_data'] = true;\r
1019         }\r
1020     }\r
1021     \r
1022     /**\r
1023      * handler for SINGLEQUOTE.\r
1024      * this handler recognizes strings defined with single quotation marks (') and handles them correctly\r
1025      * in any place that they legally appear in php code\r
1026      */\r
1027     \r
1028     function handleSingleQuote($word, $pevent)\r
1029     {\r
1030         $this->checkEventPush( $word, $pevent);\r
1031         if ($this->checkEventPop($word,$pevent))\r
1032         {\r
1033             if ($this->p_vars['last_word'] != "'")\r
1034             {\r
1035                 $this->p_vars['quote_data'] = $this->p_vars['last_word'];\r
1036             } else {\r
1037                 $this->p_vars['quote_data'] = "";\r
1038             }\r
1039         }\r
1040     }\r
1041 \r
1042     /**\r
1043      * handler for EOFQUOTE.\r
1044      * this handler recognizes strings defined with perl-style <<< EOF quotes, and handles them correctly\r
1045      * in any place that they legally appear in php code\r
1046      *\r
1047      * an example:\r
1048      * <code>$var <<< EOF\r
1049      * blah blah blah\r
1050      * EOF;</code>\r
1051      */\r
1052     \r
1053     function handleEOFQuote($word, $pevent)\r
1054     {\r
1055         //    echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|$this->p_vars['last_word']|\n";\r
1056         if (trim($this->p_vars['last_word']) == "<<<")\r
1057         {\r
1058             // ok we found the keyword\r
1059             //echo "Keyword == $word\n";\r
1060             $this->p_vars['oldtoken'] = $this->tokens[STATE_EOFQUOTE];\r
1061             $this->tokens[STATE_EOFQUOTE] = array($word);\r
1062         } \r
1063         else if ($this->p_vars['last_pevent'] || PARSER_EVENT_EOFQUOTE) \r
1064         {\r
1065             // i don't think anything will ever use this so were not going to set it\r
1066             //$this->p_vars['quote_data'] = $this->p_vars['last_word']; \r
1067             $this->p_vars['event_stack']->popEvent();\r
1068             $this->tokens[STATE_EOFQUOTE] = $this->p_vars['oldtoken'];\r
1069         }\r
1070     }\r
1071     /**#@-*/\r
1072 \r
1073     /**\r
1074      * Tells the parser to search for a global variable definition as\r
1075      * defined by a @global type $name tag.\r
1076      *\r
1077      * The parser is fooled into looking for the entire global variable as a\r
1078      * single token by amending the {@link $tokens} array.\r
1079      *\r
1080      * {@source}\r
1081      * @access private\r
1082      * @param string name of global variable as it appears in the source code\r
1083      */\r
1084     function findGlobal($name)\r
1085     {\r
1086         if (!isset($this->p_vars['globaltofind']))\r
1087         {\r
1088             $this->p_vars['globaltofind'] = $name;\r
1089             $this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($name)] = PARSER_EVENT_DEFINE_GLOBAL;\r
1090             $this->tokens[STATE_PHPCODE][] = $name;\r
1091         } else\r
1092         {\r
1093             addError(PDERROR_MULTIPLE_GLOBAL_TAGS,$this->p_vars['globaltofind'],$name);\r
1094         }\r
1095     }\r
1096     \r
1097     /**#@+\r
1098      * @access private\r
1099      * @param string token parsed from source\r
1100      * @param integer parser constant from {@link Parser.inc}\r
1101      */\r
1102     /**\r
1103      * handler for PHPCODE.\r
1104      * this handler recognizes the <code><?</code> php processor directive, and begins parsing php code\r
1105      */\r
1106     \r
1107     function handlePhpCode($word, $pevent)\r
1108     {\r
1109         $e = $this->checkEventPush( $word, $pevent);\r
1110         if ($e == PARSER_EVENT_DOCBLOCK || $e == PARSER_EVENT_DOCBLOCK_TEMPLATE)\r
1111         {\r
1112             $this->wp->setWhitespace(true);\r
1113         }\r
1114         if (isset($this->p_vars['globaltofind']) && $e)\r
1115         {\r
1116             if ($e != PARSER_EVENT_DEFINE_GLOBAL && $e != PARSER_EVENT_ARRAY && $e != PARSER_EVENT_QUOTE && $e != PARSER_EVENT_SINGLEQUOTE && $e != PARSER_EVENT_COMMENT && $e != PARSER_EVENT_COMMENTBLOCK)\r
1117             {\r
1118                 addError(PDERROR_GLOBAL_NOT_FOUND,$this->p_vars['globaltofind']);\r
1119                 unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);\r
1120                 foreach($this->tokens[STATE_PHPCODE] as $i => $notme)\r
1121                 if ($this->tokens[STATE_PHPCODE][$i] == $this->p_vars['globaltofind'])\r
1122                 unset($this->tokens[STATE_PHPCODE][$i]);\r
1123                 unset($this->p_vars['globaltofind']);\r
1124             }\r
1125         }\r
1126     }\r
1127     \r
1128     /**\r
1129      * handler for global variables\r
1130      */\r
1131     function handleGlobal($word, $pevent)\r
1132     {\r
1133         if (!$this->p_flags['in_global'])\r
1134         {\r
1135             $this->p_vars['linenum'] = $this->wp->linenum;\r
1136         }\r
1137         $this->p_flags['in_global'] = true;\r
1138         $e = $this->checkEventPush($word, $pevent);\r
1139         if ($this->checkEventPop($word, $pevent))\r
1140         {\r
1141             $this->p_flags['in_global'] = false;\r
1142             $a = new parserGlobal;\r
1143             $a->setDataType($this->p_vars['global_type']);\r
1144             $this->p_vars['global_type'] = '';\r
1145             $a->setLineNumber($this->p_vars['linenum']);\r
1146             $a->setName($this->p_vars['globaltofind']);\r
1147             if (isset($this->p_vars['global_val']))\r
1148             $a->setValue(trim($this->p_vars['global_val']));\r
1149             unset($this->p_vars['global_val']);\r
1150             $this->publishEvent(PHPDOCUMENTOR_EVENT_GLOBAL,$a);\r
1151             unset($this->pushEvent[PARSER_EVENT_PHPCODE][strtolower($this->p_vars['globaltofind'])]);\r
1152             foreach($this->tokens[STATE_PHPCODE] as $i => $notme)\r
1153             if ($this->tokens[STATE_PHPCODE][$i] == $this->p_vars['globaltofind'])\r
1154             unset($this->tokens[STATE_PHPCODE][$i]);\r
1155             unset($this->p_vars['globaltofind']);\r
1156         }\r
1157     }\r
1158     \r
1159     /**\r
1160      * Handles the stuff after the = in <code>$globalvar = value</code>\r
1161      */\r
1162     function handleGlobalValue($word, $pevent)\r
1163     {\r
1164         if ($this->checkEventPush($word, $pevent))\r
1165         {\r
1166             $this->wp->setWhitespace(false);\r
1167             return;\r
1168         }\r
1169         if (!isset($this->p_vars['global_val'])) $this->p_vars['global_val'] = '';\r
1170         if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE)\r
1171         {\r
1172             if (!isset($this->p_vars['quote_data'])) $this->p_vars['quote_data'] = '';\r
1173             $this->p_vars['global_val'] .= '"'.$this->p_vars['quote_data'].'"';\r
1174             unset($this->p_vars['quote_data']);\r
1175             $this->p_vars['last_pevent'] = PARSER_EVENT_GLOBAL_VALUE;\r
1176         }\r
1177         if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)\r
1178         {\r
1179             $this->p_vars['global_val'] .= $this->p_vars['function_data'];\r
1180             $this->p_vars['function_data'] = false;\r
1181         }\r
1182         if ($word != ';')\r
1183         $this->p_vars['global_val'] .= $word;\r
1184         if ($this->checkEventPop($word, $pevent))\r
1185         {\r
1186             $this->wp->setWhitespace(false);\r
1187             $this->wp->backupPos($word);\r
1188         }\r
1189     }\r
1190     \r
1191     /**\r
1192      * handler for FUNC_GLOBAL.\r
1193      * this handler recognizes "global $var1, $var2" declarations in a function, and parses them\r
1194      */\r
1195     \r
1196     function handleFuncGlobal($word, $pevent)\r
1197     {\r
1198         if ((substr(trim($word),0,1) != '$') && ($word != ',') && ($word != ';'))\r
1199         { // not a global declaration, using a variable named "$global"\r
1200             $this->p_vars['event_stack']->popEvent();\r
1201             return;\r
1202         }\r
1203         if ($this->checkEventPop($word, $pevent))\r
1204         {\r
1205             return;\r
1206         }\r
1207         if (!$this->checkEventPush($word, $pevent))\r
1208         {\r
1209             if ($word == ',')\r
1210             { // another variable\r
1211                 $this->p_vars['global_count']++;\r
1212             } else\r
1213             {\r
1214                 if (!isset($this->p_vars['globals'][$this->p_vars['global_count']]))\r
1215                 $this->p_vars['globals'][$this->p_vars['global_count']] = '';\r
1216                 if (!empty($this->p_vars['globals'][$this->p_vars['global_count']])) $this->p_vars['global_count']++;\r
1217                 $this->p_vars['globals'][$this->p_vars['global_count']] = trim($word);\r
1218             }\r
1219         }\r
1220     }\r
1221     \r
1222     /**\r
1223      * handler for STATIC_VAR.\r
1224      * this handler recognizes "static $var1, $var2 = 6" declarations in a function, and parses them\r
1225      */\r
1226     \r
1227     function handleStaticVar($word, $pevent)\r
1228     {\r
1229         if ($this->checkEventPop($word, $pevent))\r
1230         {\r
1231             $this->p_vars['static_count']++;\r
1232             return;\r
1233         }\r
1234         if (!$this->checkEventPush($word, $pevent))\r
1235         {\r
1236             if ($word == ',')\r
1237             {\r
1238                 $this->p_vars['static_count']++;\r
1239                 return;\r
1240             }\r
1241             if (!isset($this->p_vars['statics'][$this->p_vars['static_count']]))\r
1242             $this->p_vars['statics'][$this->p_vars['static_count']] = '';\r
1243             if (!empty($this->p_vars['statics'][$this->p_vars['static_count']])) $this->p_vars['static_count']++;\r
1244             $this->p_vars['statics'][$this->p_vars['static_count']] = trim($word);\r
1245         }\r
1246     }\r
1247     \r
1248     /**\r
1249      * handler for STATIC_VAR_VALUE.\r
1250      * this handler parses the 6 in "static $var1, $var2 = 6"\r
1251      */\r
1252     \r
1253     function handleStaticValue($word, $pevent)\r
1254     {\r
1255         if ($this->checkEventPush($word, $pevent))\r
1256         {\r
1257             return;\r
1258         }\r
1259         if (!isset($this->p_vars['static_val'][$this->p_vars['static_count']])) $this->p_vars['static_val'][$this->p_vars['static_count']] = '';\r
1260         if ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE || $this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE)\r
1261         {\r
1262             $this->p_vars['static_val'][$this->p_vars['static_count']] .= '"'.$this->p_vars['quote_data'].'"';\r
1263             unset($this->p_vars['quote_data']);\r
1264         }\r
1265         if ($this->p_vars['last_pevent'] == PARSER_EVENT_ARRAY)\r
1266         {\r
1267             $this->p_vars['static_val'][$this->p_vars['static_count']] .= $this->p_vars['function_data'];\r
1268             $this->p_vars['function_data'] = false;\r
1269         }\r
1270         if ($this->checkEventPop($word, $pevent))\r
1271         {\r
1272             $this->p_vars['static_val'][$this->p_vars['static_count']] = trim($this->p_vars['static_val'][$this->p_vars['static_count']]);\r
1273             $this->wp->backupPos($word);\r
1274             return;\r
1275         } else $this->p_vars['static_val'][$this->p_vars['static_count']] .= $word;\r
1276     }\r
1277     \r
1278     /**\r
1279      * handler for FUNCTION.\r
1280      * this handler recognizes function declarations, and parses them.  The body\r
1281      * of the function is parsed by handleLogicBlock()\r
1282      * @see handleLogicBlock()\r
1283      */\r
1284     \r
1285     function handleFunction($word, $pevent)\r
1286     {\r
1287         if ($e = $this->checkEventPush( $word, $pevent))\r
1288         {\r
1289             if ($e == PARSER_EVENT_COMMENT || $e == PARSER_EVENT_COMMENTBLOCK) return;\r
1290         }\r
1291     \r
1292         if (!isset($this->p_vars['func'])) $this->p_vars['func'] = false;\r
1293         if (! is_subclass_of($this->p_vars['func'],"parserBase")) \r
1294         {\r
1295             $this->p_vars['globals'] = array();\r
1296             $this->p_vars['global_count'] = 0;\r
1297             if ($this->p_flags['in_class'])\r
1298             $this->p_vars['func'] = new parserMethod($this->p_vars['cur_class']); \r
1299             else\r
1300             $this->p_vars['func'] = new parserFunction;\r
1301             $this->p_vars['func']->setLineNumber($this->wp->linenum);\r
1302             if (trim($word) != '&')\r
1303             $this->p_vars['func']->setName(trim($word));\r
1304             else\r
1305             $this->p_vars['func']->setReturnsReference();\r
1306         } else\r
1307         {\r
1308             if ($this->p_vars['func']->getReturnsReference())\r
1309             {\r
1310                 if ($this->p_vars['last_word'] == '&')\r
1311                 {\r
1312                     $this->p_vars['func']->setName(trim($word));\r
1313                 }\r
1314             }\r
1315         }\r
1316         if ($this->checkEventPop($word,$pevent)) \r
1317         { \r
1318             $this->p_vars['func']->addGlobals($this->p_vars['globals']);\r
1319             $this->p_vars['func']->addStatics($this->p_vars['statics'],$this->p_vars['static_val']);\r
1320             $this->p_vars['globals'] = array();\r
1321             $this->p_vars['global_count'] = 0;\r
1322             if ($this->p_flags['getting_source'])\r
1323             {\r
1324                 $x = $this->wp->getSource();\r
1325                 $this->p_vars['func']->addSource($x);\r
1326                 $this->p_flags['get_source'] = false;\r
1327                 $this->p_flags['getting_source'] = false;\r
1328             }\r
1329             $this->publishEvent(PHPDOCUMENTOR_EVENT_FUNCTION,$this->p_vars['func']); \r
1330             $this->p_vars['func'] = false; \r
1331         } \r
1332     }\r
1333 \r
1334     /**#@-*/\r
1335     /**\r
1336      * Helper function for {@link handleFunctionParams()}\r
1337      *\r
1338      * This function adds a new parameter to the parameter list\r
1339      * @access private\r
1340      * @param string\r
1341      */\r
1342     function endFunctionParam($word)\r
1343     {\r
1344         if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))\r
1345         {\r
1346             $this->p_vars['function_data'] .= "'".$this->p_vars['quote_data']."'";\r
1347             unset($this->p_vars['quote_data']);\r
1348         }\r
1349         if (isset($this->p_vars['quote_data']) && ($this->p_vars['quote_data'] != '') && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE))\r
1350         {\r
1351             $this->p_vars['function_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
1352             unset($this->p_vars['quote_data']);\r
1353         }\r
1354         if (isset($this->p_vars['function_param']))\r
1355         {\r
1356             $this->p_vars['func']->addParam($this->p_vars['function_param'],$this->p_vars['function_data'], $this->p_flags['funcparam_val']);\r
1357             unset($this->p_vars['function_param']);\r
1358             $this->p_vars['function_data'] = '';\r
1359             $this->p_flags['funcparam_val'] = false;\r
1360         }\r
1361     }\r
1362     /**#@+\r
1363      * @access private\r
1364      * @param string token parsed from source\r
1365      * @param integer parser constant from {@link Parser.inc}\r
1366      */\r
1367     /**\r
1368      * handler for FUNCTION_PARAMS.\r
1369      * this handler recognizes the parameters of a function within parentheses like function(param, param = default_value)\r
1370      * and parses them\r
1371      * @see endFunctionParam()\r
1372      */\r
1373     \r
1374     function handleFunctionParams($word, $pevent)\r
1375     {\r
1376         //echo $this->wp->getPos() . ": word=|$word|\t\t\tlastword=|".$this->p_vars['last_word']."|\n";\r
1377         //echo "function_param = '".$this->p_vars['function_param']."'\n";\r
1378         //echo "function_data = '".$this->p_vars['function_data']."'\n";\r
1379         $e1 = $this->checkEventPush( $word, $pevent); \r
1380 \r
1381         if (!$e1)\r
1382         {\r
1383             if ($word == ',' || $this->checkEventPop($word,$pevent))\r
1384             {\r
1385                 $this->endFunctionParam($word);\r
1386             } elseif ($word == '=')\r
1387             {\r
1388                 $this->p_flags['funcparam_val'] = true;\r
1389             } else\r
1390             {\r
1391                 if ($this->p_flags['funcparam_val'])\r
1392                 {\r
1393                     if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_SINGLEQUOTE))\r
1394                     {\r
1395                         $this->p_vars['function_data'] .= "'".$this->p_vars['quote_data']."'";\r
1396                         unset($this->p_vars['quote_data']);\r
1397                     }\r
1398                     if (isset($this->p_vars['quote_data']) && ($this->p_vars['last_pevent'] == PARSER_EVENT_QUOTE))\r
1399                     {\r
1400                         $this->p_vars['function_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
1401                         unset($this->p_vars['quote_data']);\r
1402                     }\r
1403                     $this->p_vars['function_data'] .= $word;\r
1404                 } else\r
1405                 {\r
1406                     $this->p_vars['function_param'] = $word;\r
1407                 }\r
1408             }\r
1409         }\r
1410     }\r
1411 \r
1412     \r
1413     /**\r
1414      * javadoc-desc-compliant handler for DOCBLOCK.\r
1415      * this handler recognizes @tags in DocBlocks and parses them for display.\r
1416      * It also parses out unknown tags into their own array for use by the docblock\r
1417      */\r
1418     \r
1419     function JavaDochandleDocblock($word, $pevent)\r
1420     {\r
1421         $e1 = $this->checkEventPush( $word, $pevent);\r
1422         if (!isset($this->p_vars[$this->p_vars['docblock_type']]) || !$this->p_vars[$this->p_vars['docblock_type']])\r
1423         {\r
1424             $this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();\r
1425             $this->p_vars['returntype'] = false;\r
1426             $this->p_vars['vartype'] = false;\r
1427             $this->p_flags['startdocblock'] = true;\r
1428             $this->p_flags['valid_newline'] = true;\r
1429             $this->p_flags['startline'] = true;\r
1430             $this->p_flags['newline'] = true;\r
1431             $this->p_flags['in_desc'] = true;\r
1432             $this->p_flags['in_tag'] = false;\r
1433             $this->p_flags['useperiod'] = false;\r
1434             $this->p_vars['line'] = array();\r
1435             $this->p_vars['linecount'] = 0;\r
1436         }\r
1437         $e = $this->checkEventPop( $word, $pevent);\r
1438         if (!$e1 && !$e)\r
1439         {\r
1440             if ($this->p_flags['in_desc']) $this->JavaDochandleDesc($word, $pevent);\r
1441             else $this->handleTags($word, $pevent);\r
1442         }\r
1443         if ($e)\r
1444         {\r
1445             if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'] = 0;\r
1446             if ($this->p_vars['periodline'] > 3)\r
1447             {\r
1448                 $this->p_flags['useperiod'] = false;\r
1449             }\r
1450 \r
1451             $this->p_vars['docblock_desc'] = new parserDesc;\r
1452 //            echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";\r
1453             if ($this->p_vars['docblock_type'] == 'docblock')\r
1454             {\r
1455                 if (isset($this->p_vars['docblock_template']))\r
1456                 {\r
1457                     // copy template values if not overridden\r
1458                     if (!$this->p_vars['docblock']->getExplicitPackage())\r
1459                     {\r
1460                         if ($p = $this->p_vars['docblock_template']->getKeyword('package'))\r
1461                         {\r
1462                             $this->p_vars['docblock']->addKeyword('package',$p);\r
1463                             $this->p_vars['docblock']->setExplicitPackage();\r
1464                         }\r
1465                         if ($p = $this->p_vars['docblock_template']->getKeyword('category'))\r
1466                         {\r
1467                             $this->p_vars['docblock']->addKeyword('category',$p);\r
1468                             $this->p_vars['docblock']->setExplicitCategory();\r
1469                         }\r
1470                         if ($p = $this->p_vars['docblock_template']->getKeyword('subpackage'))\r
1471                         {\r
1472                             $this->p_vars['docblock']->addKeyword('subpackage',$p);\r
1473                         }\r
1474                     }\r
1475                     $tags = $this->p_vars['docblock_template']->listTags();\r
1476                     foreach($tags as $tag)\r
1477                     {\r
1478                         $this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);\r
1479                     }\r
1480                     $this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);\r
1481                     if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params = $this->p_vars['docblock_template']->params;\r
1482                 }\r
1483                 if ($a = strpos(trim($this->p_vars['shortdesc']),'<p>') === 0)\r
1484                 $this->p_vars['shortdesc'] = substr($this->p_vars['shortdesc'],strpos($this->p_vars['shortdesc'],'<p>') + 4);\r
1485                 $this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);\r
1486             }\r
1487             for($i = 0; $i < count($this->p_vars['line']); $i++)\r
1488             {\r
1489                 // the line will not be set if it doesn't start with a *\r
1490                 if (isset($this->p_vars['line'][$i]))\r
1491                 $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);\r
1492             }\r
1493 \r
1494 \r
1495             $this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);\r
1496             unset($this->p_vars['docblock_desc']);\r
1497 //            var_dump($this->p_vars[$this->p_vars['docblock_type']]);\r
1498 //            exit;\r
1499             if ($this->p_vars['docblock_type'] == 'docblock')\r
1500             {\r
1501                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);\r
1502                 unset($this->p_vars[$this->p_vars['docblock_type']]);\r
1503                 $this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();\r
1504             }\r
1505             $this->p_flags['in_desc'] = true;\r
1506             $this->p_flags['in_tag'] = false;\r
1507             $this->p_flags['useperiod'] = false;\r
1508             $this->p_vars['line'] = array();\r
1509             $this->p_vars['linecount'] = 0;\r
1510             $this->p_flags['start_docblock'] = true;\r
1511             $this->p_flags['valid_newline'] = true;\r
1512             $this->wp->setWhitespace(false);\r
1513         }\r
1514     }\r
1515 \r
1516     /**\r
1517      * handler for DOCKEYWORD_DESC.\r
1518      * this handler parses the short and long description of a dockeyword\r
1519      */\r
1520     \r
1521     function JavaDochandleDesc($word, $pevent)\r
1522     {\r
1523         if ($this->p_flags['valid_newline'])\r
1524         {\r
1525             if ($word == '@' && $this->p_flags['startline'])\r
1526             {\r
1527                 return $this->handleTag($word, $pevent);\r
1528             }\r
1529             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
1530             {\r
1531                 $this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;\r
1532             }\r
1533             if ($this->p_vars['last_word'] == "." && $this->p_flags['useperiod'] == false)\r
1534             {\r
1535                 $this->p_vars['periodline'] = $this->p_vars['linecount'];\r
1536                 $this->p_vars['shortdesc'] = new parserDesc;\r
1537                 for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)\r
1538                 {\r
1539                     if (isset($this->p_vars['line'][$i]))\r
1540                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);\r
1541                 }\r
1542                 $this->p_flags['useperiod'] = true;\r
1543             }\r
1544             $this->p_vars['line'][$this->p_vars['linecount']]->add($word);\r
1545 //            debug("DESC $word");\r
1546         }\r
1547         $this->handleCR($word);\r
1548     }\r
1549     \r
1550     /**\r
1551      * handler for DOCBLOCK.\r
1552      * this handler recognizes @tags in DocBlocks and parses them for display.\r
1553      * It also parses out unknown tags into their own array for use by the docblock\r
1554      */\r
1555     \r
1556     function BetterhandleDocblock($word, $pevent)\r
1557     {\r
1558         $e1 = $this->checkEventPush( $word, $pevent);\r
1559         if (!$this->wp->returnWhiteSpace)\r
1560         {\r
1561             addErrorDie(PDERROR_NEED_WHITESPACE);\r
1562         }\r
1563         if (!isset($this->p_vars[$this->p_vars['docblock_type']]) || !$this->p_vars[$this->p_vars['docblock_type']])\r
1564         {\r
1565             $this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();\r
1566             $this->p_vars['returntype'] = false;\r
1567             $this->p_vars['vartype'] = false;\r
1568             $this->p_flags['startdocblock'] = true;\r
1569             $this->p_flags['valid_newline'] = true;\r
1570             $this->p_flags['startline'] = true;\r
1571             $this->p_flags['newline'] = true;\r
1572             $this->p_flags['in_desc'] = true;\r
1573             $this->p_flags['in_tag'] = false;\r
1574             $this->p_flags['useperiod'] = false;\r
1575             $this->p_vars['line'] = array();\r
1576             $this->p_vars['linecount'] = 0;\r
1577         }\r
1578         $e = $this->checkEventPop( $word, $pevent);\r
1579         if (!$e1 && !$e)\r
1580         {\r
1581             if ($this->p_flags['in_desc']) $this->handleDesc($word, $pevent);\r
1582             else $this->handleTags($word, $pevent);\r
1583         }\r
1584         if ($e)\r
1585         {\r
1586             if (!isset($this->p_vars['periodline'])) $this->p_vars['periodline'] = 0;\r
1587             if ($this->p_vars['periodline'] > 3)\r
1588             {\r
1589                 $this->p_flags['useperiod'] = false;\r
1590             } else\r
1591             {\r
1592                 for($i = 0; $i < $this->p_vars['periodline']; $i++)\r
1593                 {\r
1594                     if (isset($this->p_vars['line'][$i]))\r
1595                     {\r
1596                         if ($this->p_vars['line'][$i]->trimmedStrlen() == 0 && isset($this->p_vars['line'][$i - 1]) && $this->p_vars['line'][$i - 1]->trimmedStrlen())\r
1597                         {\r
1598                             $this->p_vars['periodline'] = $i;\r
1599                         }\r
1600                     }\r
1601                 }\r
1602             }\r
1603             // figure out the shortdesc\r
1604             if ($this->p_flags['useperiod'] === false)\r
1605             {\r
1606                 // use the first non blank line for short desc\r
1607                 for($i = 0; $i < count($this->p_vars['line']); $i++)\r
1608                 {\r
1609                     if (!isset($this->p_vars['line'][$i]))\r
1610                     $this->p_vars['line'][$i] = new parserStringWithInlineTags;\r
1611                     if ($this->p_vars['line'][$i]->trimmedStrlen() > 0)\r
1612                     {\r
1613                         $this->p_vars['periodline'] = $i;\r
1614                         $i = count($this->p_vars['line']);\r
1615                     }\r
1616                 }\r
1617                         \r
1618                 // check to see if we are going to use a blank line to end the shortdesc\r
1619                 // this can only be in the first 4 lines\r
1620                 if (count($this->p_vars['line']) > 4)\r
1621                 {\r
1622                     $max = 4;\r
1623                 } else {\r
1624                     $max = count($this->p_vars['line']);\r
1625                 }\r
1626 \r
1627                 for($i = $this->p_vars['periodline']; $i < $max; $i++)\r
1628                 {\r
1629                     if (isset($this->p_vars['line'][$i]))\r
1630                     if ($this->p_vars['line'][$i]->trimmedStrlen() == 0)\r
1631                     {\r
1632                         $this->p_vars['periodline'] = $i;\r
1633                         $i = $max;\r
1634                     }\r
1635                 }\r
1636             }\r
1637 \r
1638             if ($this->p_vars['docblock_type'] == 'docblock')\r
1639             {\r
1640                 $this->p_vars['shortdesc'] = new parserDesc;\r
1641                 for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)\r
1642                 {\r
1643                     if (isset($this->p_vars['line'][$i]))\r
1644                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);\r
1645                 }\r
1646                 $this->p_vars['periodline']++;\r
1647     \r
1648                 $this->p_vars['docblock_desc'] = new parserDesc;\r
1649                 if (isset($this->p_vars['docblock_template']))\r
1650                 {\r
1651                     // copy template values if not overridden\r
1652                     if (!$this->p_vars['docblock']->getExplicitPackage())\r
1653                     {\r
1654                         if ($p = $this->p_vars['docblock_template']->getKeyword('package'))\r
1655                         {\r
1656                             $this->p_vars['docblock']->addKeyword('package',$p);\r
1657                             $this->p_vars['docblock']->setExplicitPackage();\r
1658                         }\r
1659                         if ($p = $this->p_vars['docblock_template']->getKeyword('category'))\r
1660                         {\r
1661                             $this->p_vars['docblock']->addKeyword('category',$p);\r
1662                             $this->p_vars['docblock']->setExplicitCategory();\r
1663                         }\r
1664                         if ($p = $this->p_vars['docblock_template']->getKeyword('subpackage'))\r
1665                         {\r
1666                             $this->p_vars['docblock']->addKeyword('subpackage',$p);\r
1667                         }\r
1668                     }\r
1669                     $tags = $this->p_vars['docblock_template']->listTags();\r
1670                     foreach($tags as $tag)\r
1671                     {\r
1672                         $this->p_vars['docblock']->addKeyword($tag->keyword,$tag->value);\r
1673                     }\r
1674                     if (!count($this->p_vars['docblock']->params)) $this->p_vars['docblock']->params = $this->p_vars['docblock_template']->params;\r
1675                     $this->p_vars['docblock_desc']->add($this->p_vars['docblock_template']->desc);\r
1676                 }\r
1677     //            echo "i = ".$this->p_vars['periodline']."; i < " . count($this->p_vars['line']) . "\n";\r
1678                 for($i = $this->p_vars['periodline']; $i < count($this->p_vars['line']); $i++)\r
1679                 {\r
1680                     // the line will not be set if it doesn't start with a *\r
1681                     if (isset($this->p_vars['line'][$i]))\r
1682                     $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);\r
1683                 }\r
1684             } else\r
1685             {\r
1686                 $this->p_vars['shortdesc'] = new parserDesc;\r
1687                 for($i = 0; ($i <= $this->p_vars['periodline']) && ($i < count($this->p_vars['line'])); $i++)\r
1688                 {\r
1689                     if (isset($this->p_vars['line'][$i]))\r
1690                     $this->p_vars['shortdesc']->add($this->p_vars['line'][$i]);\r
1691                 }\r
1692                 $this->p_vars['periodline']++;\r
1693     \r
1694                 $this->p_vars['docblock_desc'] = new parserDesc;\r
1695                 for($i=$this->p_vars['periodline']; $i < count($this->p_vars['line']); $i++)\r
1696                 {\r
1697                     if (isset($this->p_vars['line'][$i]))\r
1698                     $this->p_vars['docblock_desc']->add($this->p_vars['line'][$i]);\r
1699                 }\r
1700             }\r
1701 \r
1702 \r
1703             $this->p_vars[$this->p_vars['docblock_type']]->setShortDesc($this->p_vars['shortdesc']);\r
1704             $this->p_vars[$this->p_vars['docblock_type']]->setDesc($this->p_vars['docblock_desc']);\r
1705             unset($this->p_vars['docblock_desc']);\r
1706 //            var_dump($this->p_vars[$this->p_vars['docblock_type']]);\r
1707 //            exit;\r
1708             if ($this->p_vars['docblock_type'] == 'docblock')\r
1709             {\r
1710                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK,$this->p_vars[$this->p_vars['docblock_type']]);\r
1711                 unset($this->p_vars[$this->p_vars['docblock_type']]);\r
1712                 $this->p_vars[$this->p_vars['docblock_type']] = new parserDocBlock();\r
1713             } else\r
1714             {\r
1715                 $this->publishEvent(PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE,$this->p_vars[$this->p_vars['docblock_type']]);\r
1716             }\r
1717             $this->p_flags['in_desc'] = true;\r
1718             $this->p_flags['in_tag'] = false;\r
1719             $this->p_flags['useperiod'] = false;\r
1720             $this->p_vars['line'] = array();\r
1721             $this->p_vars['linecount'] = 0;\r
1722             $this->p_flags['start_docblock'] = true;\r
1723             $this->p_flags['valid_newline'] = true;\r
1724             $this->wp->setWhitespace(false);\r
1725             $this->p_vars['docblock_type'] = 'docblock';\r
1726         }\r
1727     }\r
1728     \r
1729     /**\r
1730      * Handles docblock templates\r
1731      * @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate\r
1732      */\r
1733     function handleDocBlockTemplate($word, $pevent)\r
1734     {\r
1735         $this->p_vars['docblock_type'] = 'docblock_template';\r
1736         $this->p_vars['event_stack']->popEvent();\r
1737         $this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCBLOCK);\r
1738         // fool the docblock handler into thinking everything is totally normal\r
1739         $this->p_vars['last_word'] = '/**';\r
1740         $pevent = PARSER_EVENT_DOCBLOCK;\r
1741         $this->BetterhandleDocBlock($word, $pevent);\r
1742     }\r
1743     \r
1744     /**\r
1745      * Handles closing docblock templates /**#@-* /\r
1746      * @tutorial phpDocumentor.howto.pkg#basics.docblocktemplate\r
1747      */\r
1748     function handleEndDocBlockTemplate($word, $pevent)\r
1749     {\r
1750         unset($this->p_vars['docblock_template']);\r
1751         $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE);\r
1752         $this->p_vars['event_stack']->popEvent();\r
1753     }\r
1754     /**#@-*/\r
1755     /**\r
1756      * Handles a new line in a DocBlock\r
1757      * @param string token containing a newline \n\r
1758      * @access private\r
1759      */\r
1760     function handleCR($word)\r
1761     {\r
1762         $this->laststart = $this->p_flags['startline'];\r
1763         if ($word == "\n" || $word == ".\n")\r
1764         {\r
1765             $this->p_flags['start_docblock'] = false;\r
1766             $this->p_flags['newline'] = true;\r
1767             $this->p_flags['valid_newline'] = false;\r
1768             if ($this->p_flags['in_desc'] && !$this->p_flags['useperiod'])\r
1769             {\r
1770                 if ($word == ".\n")\r
1771                 {\r
1772                     $this->p_flags['useperiod'] = true;\r
1773                     $this->p_vars['periodline'] = $this->p_vars['linecount'];\r
1774                 }\r
1775             }\r
1776         } else\r
1777         {\r
1778             if ($this->p_flags['valid_newline'] && strlen(trim($word)))\r
1779             {\r
1780                 $this->p_flags['startline'] = false;\r
1781             }\r
1782             if ($this->p_flags['newline'] && ($word == '*' || $this->p_flags['start_docblock']))\r
1783             {\r
1784                 $this->p_flags['newline'] = false;\r
1785                 $this->p_flags['valid_newline'] = true;\r
1786                 if (!$this->p_flags['start_docblock'])\r
1787                 $this->p_vars['linecount']++;\r
1788                 $this->p_flags['startline'] = true;\r
1789                 $justset = true;\r
1790 //                debug('valid newline');\r
1791             }\r
1792         }\r
1793     }\r
1794     \r
1795     /**\r
1796      * handler for DOCKEYWORD_DESC.\r
1797      * this handler parses the short and long description of a dockeyword\r
1798      * @access private\r
1799      */\r
1800     \r
1801     function handleDesc($word, $pevent)\r
1802     {\r
1803 //        echo "|$word|\n";\r
1804         if ($this->p_flags['valid_newline'])\r
1805         {\r
1806             if ($word == '@' && $this->p_flags['startline'])\r
1807             {\r
1808                 return $this->handleTag($word, $pevent);\r
1809             }\r
1810             if ($this->p_vars['last_word'] == ". " || $this->p_vars['last_word'] == ".\t")\r
1811             {\r
1812                 $this->p_flags['useperiod'] = true;\r
1813                 $this->p_vars['periodline'] = $this->p_vars['linecount'];\r
1814                 $this->p_vars['linecount']++;\r
1815             }\r
1816             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
1817             {\r
1818                 $this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;\r
1819             }\r
1820             if ($this->p_flags['startline'])\r
1821             {\r
1822                 if ($word[0] == ' ') $word = substr($word,1);\r
1823 //                $word = ltrim($word," \t");\r
1824             }\r
1825             if ($word != '') $this->p_vars['line'][$this->p_vars['linecount']]->add($word);\r
1826 //            debug("DESC $word");\r
1827         }\r
1828         $this->handleCR($word);\r
1829     }\r
1830     \r
1831     /**#@+\r
1832      * @access private\r
1833      * @param string token parsed from source\r
1834      * @param integer parser constant from {@link Parser.inc}\r
1835      */\r
1836     /**\r
1837      * handler for DOCKEYWORD_TAGS.\r
1838      * this handler recognizes @tags in DocBlocks and parses them for display\r
1839      * I think this may be unused.  We'll delete from 1.1 if so\r
1840      */\r
1841     function handleTags($word, $pevent)\r
1842     {\r
1843         if ($this->p_flags['valid_newline'])\r
1844         {\r
1845 //            debug("TAGS $word");\r
1846         }\r
1847         $this->handleCR($word);\r
1848     }\r
1849     \r
1850     /**\r
1851      * handler for DOCKEYWORD.\r
1852      * this handler recognizes @tags in DocBlocks and parses them for display\r
1853      */\r
1854     function handleTag($word, $pevent)\r
1855     {\r
1856         if ($this->p_flags['in_desc'] && !$this->p_flags['valid_newline'])\r
1857         {\r
1858             $this->p_vars['event_stack']->popEvent();\r
1859             return $this->handleDesc($word, $pevent);\r
1860         }\r
1861 //        if ($this->p_vars['last_word'] == '@') fancy_debug('here'.$word,$this->p_flags['startline'],$this->p_flags['in_tag']);\r
1862         if ($this->p_vars['tagname'] == 'author')\r
1863         {\r
1864             if ($word == '<')\r
1865             {\r
1866                 $this->p_vars['event_stack']->pushEvent(PARSER_EVENT_DOCKEYWORD_EMAIL);\r
1867                 return $this->handleDockeywordEmail($word, $pevent);\r
1868             }\r
1869         }\r
1870         if ($this->checkEventPush( $word, $pevent)) return;\r
1871         if ($this->p_vars['last_word'] == '@' && !$this->p_flags['startline'] && $this->p_flags['in_desc'])\r
1872         {\r
1873             // fix 1203445\r
1874             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
1875             {\r
1876                 $this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;\r
1877             }\r
1878             $this->p_vars['event_stack']->popEvent();\r
1879             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');\r
1880             return $this->handleDesc($word, $pevent);\r
1881         } elseif($this->p_vars['last_word'] == '@' && !strlen(trim($word)) && empty($this->p_vars['tagname']) && $this->p_flags['in_desc'])\r
1882         {\r
1883             // fix 1203445\r
1884             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
1885             {\r
1886                 $this->p_vars['line'][$this->p_vars['linecount']] = new parserStringWithInlineTags;\r
1887             }\r
1888             $pevent = $this->p_vars['event_stack']->popEvent();\r
1889             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');\r
1890             return $this->handleDesc($word, $pevent);\r
1891         }\r
1892         if ($word == '@' && $this->p_flags['startline'] && $this->p_flags['in_tag'])\r
1893         {\r
1894             $this->wp->backupPos($word);\r
1895             $white = $this->wp->returnWhiteSpace;\r
1896             $this->wp->setWhitespace(true);\r
1897             $word1 = $this->wp->getWord();\r
1898             $this->wp->backupPos($word1);\r
1899             if (strlen(trim($word1)))\r
1900             {\r
1901                 $this->endTag();\r
1902             }\r
1903             $this->wp->getWord();\r
1904             $this->wp->setWhitespace($white);\r
1905         }\r
1906         $this->p_flags['in_tag'] = true;\r
1907         $e = $this->checkEventPop($word, $pevent);\r
1908         if (!$e)\r
1909         {\r
1910             if ($this->p_flags['valid_newline'])\r
1911             {\r
1912                 if (($this->p_flags['startline'] || $this->laststart) && $word != '@')\r
1913                 {\r
1914                     if ($this->p_vars['last_word'] == '@')\r
1915                     {\r
1916 //                        debug("TAGSTART $word");\r
1917                         $this->p_flags['in_tag'] = true;\r
1918                         $this->p_vars['tagname'] = $word;\r
1919                         $this->p_flags['startline'] = false;\r
1920                         $this->p_vars['tag_value'] = new parserStringWithInlineTags;\r
1921                     } else\r
1922                     {\r
1923 //                        debug("TAG1 $word");\r
1924                         if (isset($this->tagHandlers[$this->p_vars['tagname']]))\r
1925                         $handler = $this->tagHandlers[$this->p_vars['tagname']];\r
1926                         else $handler = $this->tagHandlers['*'];\r
1927                         $this->$handler($word);\r
1928                     }\r
1929                 } else\r
1930                 {\r
1931                     if (empty($this->p_vars['tagname']))\r
1932                     {\r
1933                         if ($this->p_flags['in_desc'])\r
1934                         {\r
1935                             $this->p_flags['in_tag'] = false;\r
1936                             // fix 1203445\r
1937                             if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
1938                             {\r
1939                                 $this->p_vars['line'][$this->p_vars['linecount']] =\r
1940                                     new parserStringWithInlineTags;\r
1941                             }\r
1942                             $this->p_vars['line'][$this->p_vars['linecount']]->add('@');\r
1943                             $this->p_vars['event_stack']->popEvent();\r
1944                             $this->handleCR($word);\r
1945                             return $this->handleDesc($word, $pevent);\r
1946                         }\r
1947                     }\r
1948 //                    debug("TAG2 $word");\r
1949                     if (isset($this->tagHandlers[$this->p_vars['tagname']]))\r
1950                     $handler = $this->tagHandlers[$this->p_vars['tagname']];\r
1951                     else $handler = $this->tagHandlers['*'];\r
1952                     $this->$handler($word);\r
1953                 }\r
1954             }\r
1955             $this->handleCR($word);\r
1956         }\r
1957         $this->p_flags['in_desc'] = false;\r
1958         if ($e)\r
1959         {\r
1960             $this->endTag();\r
1961             $this->wp->setWhitespace(false);\r
1962             // walk back a word\r
1963             $this->wp->backupPos($word);\r
1964             $this->wp->setWhitespace(true);\r
1965         }\r
1966     }\r
1967     /**#@-*/\r
1968     /**\r
1969      * Called to clean up at the end of parsing a @tag in a docblock\r
1970      */\r
1971     function endTag()\r
1972     {\r
1973         if (isset($this->tagHandlers[$this->p_vars['tagname']]))\r
1974         $handler = $this->tagHandlers[$this->p_vars['tagname']];\r
1975         else $handler = $this->tagHandlers['*'];\r
1976         $this->$handler(false);\r
1977         $this->p_vars['tagname'] = '';\r
1978         $this->p_flags['startline'] = true;\r
1979 //        debug("ENDTAG");\r
1980     }\r
1981     \r
1982     /**#@+\r
1983      * Tag Handlers\r
1984      * @param string\r
1985      */\r
1986     /**\r
1987      * Handles all standard tags that only have a description\r
1988      */\r
1989     function defaultTagHandler($word)\r
1990     {\r
1991         if ($word !== false)\r
1992         {\r
1993             $this->p_vars['tag_value']->add($word);\r
1994         } else\r
1995         {\r
1996             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);\r
1997         }\r
1998     }\r
1999     \r
2000     /**\r
2001      * Handles tags like '@filesource' that only work in PHP 4.3.0+\r
2002      */\r
2003     function invalidTagHandler($word)\r
2004     {\r
2005         if ($word === false)\r
2006         {\r
2007             addError(PDERROR_TAG_NOT_HANDLED,$this->p_vars['tagname']);\r
2008         }\r
2009     }\r
2010     \r
2011     /**\r
2012      * handles @package\r
2013      * @tutorial tags.package.pkg\r
2014      */\r
2015     function packageTagHandler($word)\r
2016     {\r
2017         if ($word !== false)\r
2018         {\r
2019             $this->p_vars['tag_value']->add($word);\r
2020         } else\r
2021         {\r
2022             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);\r
2023             $this->p_vars[$this->p_vars['docblock_type']]->setExplicitPackage();\r
2024         }\r
2025     }\r
2026     \r
2027     /**\r
2028      * handles @example\r
2029      * @tutorial tags.example.pkg\r
2030      */\r
2031     function exampleTagHandler($word)\r
2032     {\r
2033         if ($word !== false)\r
2034         {\r
2035             $this->p_vars['tag_value']->add($word);\r
2036         } else\r
2037         {\r
2038             $this->p_vars[$this->p_vars['docblock_type']]->addExample($this->p_vars['tag_value'], $this->p_vars['parsepath']);\r
2039         }\r
2040     }\r
2041     \r
2042     /**\r
2043      * handles @category\r
2044      * @tutorial tags.category.pkg\r
2045      */\r
2046     function categoryTagHandler($word)\r
2047     {\r
2048         if ($word !== false)\r
2049         {\r
2050             $this->p_vars['tag_value']->add($word);\r
2051         } else\r
2052         {\r
2053             $this->p_vars[$this->p_vars['docblock_type']]->addKeyword($this->p_vars['tagname'],$this->p_vars['tag_value']);\r
2054             $this->p_vars[$this->p_vars['docblock_type']]->setExplicitCategory();\r
2055         }\r
2056     }\r
2057     \r
2058     /**\r
2059      * handles @global\r
2060      * @tutorial tags.global.pkg\r
2061      */\r
2062     function globalTagHandler($word)\r
2063     {\r
2064         if ($word !== false)\r
2065         {\r
2066             // no data yet\r
2067             $a = trim($this->p_vars['tag_value']->getString());\r
2068             if (empty($a))\r
2069             {\r
2070                 // not an empty word\r
2071                 if (trim($word) != '')\r
2072                 {\r
2073                     if (!empty($this->p_vars['global_type']))\r
2074                     {\r
2075                         if (!$this->p_flags['define_global'] && !$this->p_flags['function_global'])\r
2076                         {\r
2077                             // @global type $GLOBALVARNAME ?\r
2078                             if (substr($word,0,1) == '$')\r
2079                             {\r
2080                                 $this->p_flags['define_global'] = true;\r
2081                                 $this->p_flags['function_global'] = false;\r
2082                                 $this->p_vars['find_global'] = $word;\r
2083                             } else\r
2084                             { // function @global type description\r
2085                                 $this->p_flags['function_global'] = true;\r
2086                                 $this->p_flags['define_global'] = false;\r
2087                                 $this->p_vars['tag_value']->add($word);\r
2088                             }\r
2089                         } else\r
2090                         {\r
2091                             if ($this->p_flags['define_global'])\r
2092                             {\r
2093                                 $this->p_vars['find_global'] .= $word;\r
2094                             } elseif($this->p_flags['function_global'])\r
2095                             {\r
2096                                 // description, to be added to the tag\r
2097                                 $this->p_vars['tag_value']->add($word);\r
2098                             }\r
2099                         }\r
2100                     } else\r
2101                     {\r
2102                         $this->p_vars['global_type'] = $word;\r
2103                     } \r
2104                 } else $this->p_vars['tag_value']->add($word); // add whitespace to the tag description\r
2105             } else\r
2106             { // tag_value has data, must be a function @global\r
2107                 $this->p_vars['tag_value']->add($word);\r
2108             }\r
2109         } else\r
2110         { // endtag\r
2111             if ($this->p_flags['define_global'])\r
2112             {\r
2113                 $this->findGlobal($this->p_vars['find_global']);\r
2114             }\r
2115             elseif ($this->p_flags['function_global'])\r
2116             {\r
2117                 $this->p_vars[$this->p_vars['docblock_type']]->addFuncGlobal($this->p_vars['global_type'],$this->p_vars['tag_value']);\r
2118                 $this->p_vars['global_type'] = '';\r
2119             }\r
2120             else\r
2121             {\r
2122                 addError(PDERROR_MALFORMED_GLOBAL_TAG);\r
2123             }\r
2124             $this->p_vars['find_global'] = '';\r
2125             $this->p_flags['define_global'] = false;\r
2126             $this->p_flags['function_global'] = false;\r
2127         }\r
2128     }\r
2129     \r
2130     /**\r
2131      * handles @staticvar\r
2132      * @tutorial tags.staticvar.pkg\r
2133      */\r
2134     function staticvarTagHandler($word)\r
2135     {\r
2136         if ($word !== false)\r
2137         {\r
2138             if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);\r
2139             else\r
2140             {\r
2141                 if (!$this->p_vars['paramname'])\r
2142                 {\r
2143                     if (substr(trim($word),0,1) == "$")\r
2144                     $this->p_vars['paramname'] = trim($word);\r
2145                     else $this->p_vars['tag_value']->add($word);\r
2146                 } else\r
2147                 {\r
2148                     if (0)//strtolower($this->p_vars['paramtype']) == 'object')\r
2149                     {\r
2150                         if (strlen(trim($word)))\r
2151                         $this->p_vars['paramname'] = trim($word);\r
2152                     } else $this->p_vars['tag_value']->add($word);\r
2153                 }\r
2154             }\r
2155         } else\r
2156         {\r
2157             if (!$this->p_vars['paramname'])\r
2158             $this->p_vars[$this->p_vars['docblock_type']]->addStaticVar(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);\r
2159             else\r
2160             $this->p_vars[$this->p_vars['docblock_type']]->addStaticVar($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);\r
2161             $this->p_vars['paramname'] = false;\r
2162             $this->p_vars['returntype'] = false;\r
2163         }\r
2164     }\r
2165     \r
2166     /**\r
2167      * handles @uses\r
2168      * @tutorial tags.uses.pkg\r
2169      */\r
2170     function usesTagHandler($word)\r
2171     {\r
2172         if ($word !== false)\r
2173         {\r
2174             if (!$this->p_vars['seelement']) $this->p_vars['seelement'] = trim($word);\r
2175             else\r
2176             {\r
2177                 $this->p_vars['tag_value']->add($word);\r
2178             }\r
2179         } else\r
2180         {\r
2181             $see = new parserStringWithInlineTags;\r
2182             $see->add($this->p_vars['seelement']);\r
2183             $this->p_vars[$this->p_vars['docblock_type']]->addUses($see,$this->p_vars['tag_value']);\r
2184             $this->p_vars['seelement'] = false;\r
2185         }\r
2186     }\r
2187     \r
2188     /**\r
2189      * handles @param\r
2190      * @tutorial tags.param.pkg\r
2191      */\r
2192     function paramTagHandler($word)\r
2193     {\r
2194         if ($word !== false)\r
2195         {\r
2196             if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);\r
2197             else\r
2198             {\r
2199                 if (!$this->p_vars['paramname'])\r
2200                 {\r
2201                     if (substr(trim($word),0,1) == "$" || substr(trim($word),0,2) == "&$")\r
2202                     $this->p_vars['paramname'] = trim($word);\r
2203                     else $this->p_vars['tag_value']->add($word);\r
2204                 } else\r
2205                 {\r
2206                     if (0)//strtolower($this->p_vars['paramtype']) == 'object')\r
2207                     {\r
2208                         if (strlen(trim($word)))\r
2209                         $this->p_vars['paramname'] = trim($word);\r
2210                     } else $this->p_vars['tag_value']->add($word);\r
2211                 }\r
2212             }\r
2213         } else\r
2214         {\r
2215             if (!$this->p_vars['paramname'])\r
2216             $this->p_vars[$this->p_vars['docblock_type']]->addParam(null,$this->p_vars['returntype'],$this->p_vars['tag_value']);\r
2217             else\r
2218             $this->p_vars[$this->p_vars['docblock_type']]->addParam($this->p_vars['paramname'],$this->p_vars['returntype'],$this->p_vars['tag_value']);\r
2219             $this->p_vars['paramname'] = false;\r
2220             $this->p_vars['returntype'] = false;\r
2221         }\r
2222     }\r
2223     \r
2224     /**\r
2225      * handles @return\r
2226      * @tutorial tags.return.pkg\r
2227      */\r
2228     function returnTagHandler($word)\r
2229     {\r
2230         if ($word !== false)\r
2231         {\r
2232             if (!$this->p_vars['returntype']) $this->p_vars['returntype'] = trim($word);\r
2233             else\r
2234             {\r
2235                 if (strtolower($this->p_vars['returntype']) == 'object')\r
2236                 {\r
2237                     if (strlen(trim($word)))\r
2238                     $this->p_vars['returntype'] = trim($word);\r
2239                 } else $this->p_vars['tag_value']->add($word);\r
2240             }\r
2241         } else\r
2242         {\r
2243             $this->p_vars[$this->p_vars['docblock_type']]->addReturn($this->p_vars['returntype'],$this->p_vars['tag_value']);\r
2244             $this->p_vars['returntype'] = false;\r
2245         }\r
2246     }\r
2247     \r
2248     /**\r
2249      * handles @var\r
2250      * @tutorial tags.var.pkg\r
2251      */\r
2252     function varTagHandler($word)\r
2253     {\r
2254         if ($word)\r
2255         {\r
2256             if (!$this->p_vars['vartype']) $this->p_vars['vartype'] = trim($word);\r
2257             else\r
2258             {\r
2259                 if (strtolower($this->p_vars['vartype']) == 'object')\r
2260                 {\r
2261                     if (strlen(trim($word)))\r
2262                     $this->p_vars['vartype'] = trim($word);\r
2263                 }\r
2264                 else $this->p_vars['tag_value']->add($word);\r
2265             }\r
2266         } elseif ($word === false)\r
2267         {\r
2268             $this->p_vars[$this->p_vars['docblock_type']]->addVar($this->p_vars['vartype'],$this->p_vars['tag_value']);\r
2269             $this->p_vars['vartype'] = false;\r
2270         }\r
2271     }\r
2272     \r
2273     /**\r
2274      * Handles @property(-read or -write) and @method magic tag\r
2275      */\r
2276     function propertyTagHandler( $word )\r
2277     {\r
2278         if ( $word !== false )\r
2279         {\r
2280             if ( !$this->p_vars['returntype'] )\r
2281                 $this->p_vars['returntype'] = trim( $word );\r
2282             else\r
2283             {\r
2284                 if ( !$this->p_vars['property_name'] )\r
2285                 {\r
2286                     if ( substr( trim( $word ), 0, 1 ) == "$"\r
2287                          || substr(trim($word), 0, 2) == "&$"\r
2288                          || substr(trim($word), -2, 2) == "()"\r
2289                     )\r
2290                         $this->p_vars['property_name'] = trim( $word );\r
2291                     else\r
2292                         $this->p_vars['tag_value']->add( $word );\r
2293                 }\r
2294                 else\r
2295                 {\r
2296                     $this->p_vars['tag_value']->add( $word );\r
2297                 }\r
2298             }\r
2299         }\r
2300         else\r
2301         {\r
2302             $this->p_vars[$this->p_vars['docblock_type']]->addProperty( $this->p_vars['tagname'],\r
2303                                                                         $this->p_vars['property_name'],\r
2304                                                                         $this->p_vars['returntype'],\r
2305                                                                         $this->p_vars['tag_value'] );\r
2306             $this->p_vars['property_name'] = false;\r
2307             $this->p_vars['returntype'] = false;\r
2308         }\r
2309     }\r
2310     \r
2311     /**#@-*/\r
2312     /** @access private */\r
2313     function getSource()\r
2314     {\r
2315         $this->p_flags['get_source'] = true;\r
2316     }\r
2317     /**#@+\r
2318      * @access private\r
2319      * @param string token parsed from source\r
2320      * @param integer parser constant from {@link Parser.inc}\r
2321      */\r
2322     /**\r
2323      * handler for DOCKEYWORD_EMAIL.\r
2324      * this handler recognizes angle brackets < and > surrounding an email address in an @author tag,\r
2325      * and returns a mailto: hyperlink\r
2326      */\r
2327     \r
2328     function handleDockeywordEmail($word, $pevent)\r
2329     {\r
2330         //echo $this->wp->getPos() . ": |$word|\n";\r
2331         if (!$this->checkEventPop($word,$pevent) && $word != "<")\r
2332         {\r
2333             if (strstr($word,"@"))\r
2334             {\r
2335                 $this->p_vars['tag_value']->add('<');\r
2336                 $this->p_vars['tag_value']->add(new parserLinkInlineTag("mailto:$word",$word));\r
2337                 $this->p_vars['tag_value']->add('>');\r
2338             } else {\r
2339                 $this->p_vars['tag_value']->add("<$word>");\r
2340             }\r
2341         }\r
2342     }\r
2343 \r
2344     /**\r
2345      * handler for INLINE_DOCKEYWORD.\r
2346      * this handler recognizes {@inline tags} like link, and parses them, replacing them directly\r
2347      * in the text flow with their output.\r
2348      */\r
2349     \r
2350     function handleInlineDockeyword($word, $pevent)\r
2351     {\r
2352         //        echo $this->wp->getPos() . ": |$word|\n";\r
2353 \r
2354         //        echo "docktype: $this->p_vars['inline_dockeyword_type']\n";\r
2355         if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = false;\r
2356         if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data'] = '';\r
2357         if (!$this->p_vars['inline_dockeyword_type'])\r
2358         {\r
2359             if (in_array($word,$this->allowableInlineTags))\r
2360             {\r
2361                 if ($word == '}')\r
2362                 $this->p_vars['inline_dockeyword_type'] = '';\r
2363                 else\r
2364                 $this->p_vars['inline_dockeyword_type'] = strtolower($word);\r
2365                 $this->p_vars['whitesp'] = $this->wp->returnWhiteSpace;\r
2366                 $this->wp->setWhiteSpace(true);\r
2367             } else {\r
2368                 if ($this->p_flags['in_desc'])\r
2369                 {\r
2370                     // fix 1203445\r
2371                     if (!isset($this->p_vars['line'][$this->p_vars['linecount']]))\r
2372                     {\r
2373                         $this->p_vars['line'][$this->p_vars['linecount']] =\r
2374                             new parserStringWithInlineTags;\r
2375                     }\r
2376                     if ($word == '}')\r
2377                     {\r
2378                         $this->p_vars['line'][$this->p_vars['linecount']]->add('{@');\r
2379                     } else\r
2380                     {\r
2381                         $this->p_vars['line'][$this->p_vars['linecount']]->add('{@'.$word);\r
2382                     }\r
2383                 } elseif($this->p_flags['in_tag'])\r
2384                 {\r
2385                     if ($word == '}')\r
2386                     $this->p_vars['tag_value']->add('{@'.$word);\r
2387                     else\r
2388                     $this->p_vars['tag_value']->add('{@'.$word);\r
2389                 }\r
2390                 $this->p_vars['event_stack']->popEvent();\r
2391                 $this->p_vars['inline_dockeyword_type'] = false;\r
2392                 $this->p_vars['inline_dockeyword_data'] = '';\r
2393                 return;\r
2394             }\r
2395         } else\r
2396         {\r
2397             if ($word != "}")\r
2398             {\r
2399                 $this->p_vars['inline_dockeyword_data'] .= $word;\r
2400             }\r
2401         }\r
2402         if ($this->checkEventPop($word,$pevent))\r
2403         {\r
2404             $this->wp->setWhiteSpace($this->p_vars['whitesp']);\r
2405             if ($this->p_vars['inline_dockeyword_type']=='link')\r
2406             {\r
2407                 // support hyperlinks of any protocol\r
2408                 if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:') === 0))\r
2409                 {\r
2410                     // if there is more than 1 parameter, the stuff after the space is the hyperlink text\r
2411                     if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))\r
2412                     {\r
2413                         $i1 = strpos(trim($this->p_vars['inline_dockeyword_data']),' ') + 1;\r
2414                         $link = substr(trim($this->p_vars['inline_dockeyword_data']),0,$i1 - 1);\r
2415                         $text = substr(trim($this->p_vars['inline_dockeyword_data']),$i1);\r
2416                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($link,$text);\r
2417 //                        '<a href="'.$link.'">'.$text.'</a>';\r
2418                     }\r
2419                     else\r
2420                     {\r
2421                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
2422                     }\r
2423 //                    '<a href="'.$this->p_vars['inline_dockeyword_data'].'">'.$this->p_vars['inline_dockeyword_data'].'</a>';\r
2424                 } else\r
2425                 {\r
2426                     if (!strpos($this->p_vars['inline_dockeyword_data'],','))\r
2427                     {\r
2428                         $testp = explode('#',$this->p_vars['inline_dockeyword_data']);\r
2429                         if (count($testp) - 1)\r
2430                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$testp[1]);\r
2431                         else\r
2432                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
2433                     } else\r
2434                     $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
2435                 }\r
2436             }\r
2437             if ($this->p_vars['inline_dockeyword_type'] == 'tutorial')\r
2438             {\r
2439                 $this->p_vars['inline_dockeyword_data'] = new parserTutorialInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
2440             }\r
2441             if ($this->p_vars['inline_dockeyword_type'] == 'source')\r
2442             {\r
2443                 $this->getSource();\r
2444                 $this->p_vars['inline_dockeyword_data'] = new parserSourceInlineTag($this->p_vars['inline_dockeyword_data']);\r
2445             }\r
2446             if ($this->p_vars['inline_dockeyword_type'] == 'inheritdoc')\r
2447             {\r
2448                 $this->p_vars['inline_dockeyword_data'] = new parserInheritdocInlineTag();\r
2449             }\r
2450             if ($word == '*/')\r
2451             {\r
2452                 if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = '';\r
2453                 if (!isset($this->p_vars['tagname'])) $this->p_vars['tagname'] = '';\r
2454                 if (!isset($this->p_vars['tag_value']) || !is_object($this->p_vars['tag_value'])) $this->p_vars['tag_value'] = new parserStringWithInlineTags;\r
2455                 addError(PDERROR_UNTERMINATED_INLINE_TAG,$this->p_vars['inline_dockeyword_type'],$this->p_vars['tagname'],'@'.$this->p_vars['tagname'].' '.$this->p_vars['tag_value']->getString());\r
2456         // when we add the error class, raise error here: we reached the end of the docblock\r
2457                 $this->wp->backupPos($word); \r
2458             }\r
2459             if ($this->p_flags['in_desc'])\r
2460             {\r
2461                 $this->p_vars['line'][$this->p_vars['linecount']]->add($this->p_vars['inline_dockeyword_data']);\r
2462                 $this->p_vars['inline_dockeyword_type'] = false;\r
2463                 $this->p_vars['inline_dockeyword_data'] = '';\r
2464             }\r
2465             elseif ($this->p_flags['in_tag'])\r
2466             {\r
2467                 $this->p_vars['tag_value']->add($this->p_vars['inline_dockeyword_data']);\r
2468                 $this->p_vars['inline_dockeyword_type'] = false;\r
2469                 $this->p_vars['inline_dockeyword_data'] = '';\r
2470             }\r
2471         }\r
2472     }\r
2473 \r
2474     /**\r
2475      * handler for INCLUDE.\r
2476      * this handler recognizes include/require/include_once/include_once statements, and publishes the\r
2477      * data to Render\r
2478      */\r
2479     \r
2480     function handleInclude($word, $pevent)\r
2481     {\r
2482         if (!$this->p_flags['in_include'])\r
2483         {\r
2484             $this->p_vars['linenum'] = $this->wp->linenum;\r
2485         }\r
2486         $this->p_flags['in_include'] = true;\r
2487         $a = $this->checkEventPush( $word, $pevent);\r
2488         if (!$this->p_flags['includename_isset'])\r
2489         {\r
2490             $this->p_flags['includename_isset'] = true;\r
2491             $this->p_vars['include_name'] = $this->p_vars['last_word'];\r
2492             if ($a)\r
2493             $this->p_vars['include_value'] = '';\r
2494             else\r
2495             $this->p_vars['include_value'] = $word;\r
2496             unset($this->p_vars['quote_data']);\r
2497         } else\r
2498         {\r
2499             if (!$a)\r
2500             {\r
2501                 if (empty($this->p_vars['include_params_data']))\r
2502                 {\r
2503                     if (isset($this->p_vars['quote_data']))\r
2504                     {\r
2505                         $this->p_vars['include_value'] .= '"'.$this->p_vars['quote_data'].'"';\r
2506                         unset($this->p_vars['quote_data']);\r
2507                     }\r
2508                     if ($word != ';')\r
2509                     $this->p_vars['include_value'] .= $word;\r
2510                 }\r
2511             } else\r
2512             {\r
2513                 $this->p_vars['include_params_data'] = '';\r
2514             }\r
2515         }\r
2516 \r
2517         if ($this->checkEventPop($word,$pevent))\r
2518         {\r
2519             $this->p_vars['include'] = new parserInclude;\r
2520             $this->p_vars['include']->setLineNumber($this->p_vars['linenum']);\r
2521             $this->p_flags['in_include'] = false;\r
2522             $this->p_vars['include']->setName($this->p_vars['include_name']);\r
2523             $this->p_vars['include']->setValue($this->p_vars['include_value']);\r
2524             $this->publishEvent(PHPDOCUMENTOR_EVENT_INCLUDE,$this->p_vars['include']);\r
2525             $this->p_flags['includename_isset'] = false;\r
2526             unset($this->p_vars['include']);\r
2527             unset($this->p_vars['include_name']);\r
2528             unset($this->p_vars['include_value']);\r
2529             unset($this->p_vars['include_params_data']);\r
2530         }\r
2531     }\r
2532     \r
2533     /**\r
2534      * handler for INCLUDE_PARAMS.\r
2535      * this handler parses the contents of ( ) in include/require/include_once/include_once statements\r
2536      */\r
2537     \r
2538     function handleIncludeParams($word, $pevent)\r
2539     {\r
2540         $this->checkEventPush( $word, $pevent);\r
2541         \r
2542         $this->p_flags['include_parens'] = true;\r
2543         if(!isset($this->p_vars['include_params_data'])) $this->p_vars['include_params_data'] = '';\r
2544         \r
2545         if ($this->checkEventPop($word,$pevent))\r
2546         {\r
2547             if (isset($this->p_vars['quote_data']))\r
2548             {\r
2549                 $this->p_vars['include_value'] = $this->p_vars['include_params_data'].'"'.$this->p_vars['quote_data'].'"';\r
2550                 unset($this->p_vars['quote_data']);\r
2551             } else {\r
2552                 if (!empty($this->p_vars['include_params_data']))\r
2553                 $this->p_vars['include_value'] = $this->p_vars['include_params_data'];\r
2554                 else\r
2555                 $this->p_vars['include_value'] = trim($this->p_vars['last_word']);\r
2556             }\r
2557         }\r
2558         if (isset($this->p_vars['quote_data']))\r
2559         {\r
2560             $this->p_vars['include_params_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
2561             unset($this->p_vars['quote_data']);\r
2562         }\r
2563         if (($word != "'") && ($word != '"'))\r
2564         $this->p_vars['include_params_data'] .= $word;\r
2565     }\r
2566     \r
2567     /**\r
2568      * handler for INCLUDE_PARAMS_PARENTHESIS.\r
2569      * this handler takes all parenthetical statements within file in:\r
2570      * include statement include(file), and handles them properly\r
2571      */\r
2572     \r
2573     function handleIncludeParamsParenthesis($word, $pevent)\r
2574     {\r
2575         if (isset($this->p_vars['quote_data']))\r
2576         {\r
2577             $this->p_vars['include_params_data'] .= '"'.$this->p_vars['quote_data'].'"';\r
2578             unset($this->p_vars['quote_data']);\r
2579         }\r
2580         $this->p_vars['include_params_data'] .= $word;\r
2581         $this->checkEventPush( $word, $pevent);\r
2582         $this->checkEventPop( $word, $pevent);\r
2583     }\r
2584     /**#@-*/\r
2585     /**\r
2586      * this function checks whether parameter $word is a token for pushing a new event onto the Event Stack.\r
2587      * @return mixed    returns false, or the event number\r
2588      */\r
2589     \r
2590     function checkEventPush($word,$pevent)\r
2591     {\r
2592         $e = false;\r
2593         if (isset($this->pushEvent[$pevent]))\r
2594         {\r
2595             if (isset($this->pushEvent[$pevent][strtolower($word)]))\r
2596             $e = $this->pushEvent[$pevent][strtolower($word)];\r
2597         }\r
2598         if ($e)\r
2599         {\r
2600             $this->p_vars['event_stack']->pushEvent($e);\r
2601             return $e;\r
2602         } else {\r
2603             return false;\r
2604         }\r
2605     }\r
2606 \r
2607     /**\r
2608      * this function checks whether parameter $word is a token for popping the current event off of the Event Stack.\r
2609      * @return mixed    returns false, or the event number popped off of the stack\r
2610      */\r
2611     \r
2612     function checkEventPop($word,$pevent)\r
2613     {\r
2614         if (!isset($this->popEvent[$pevent])) return false;\r
2615         if (in_array(strtolower($word),$this->popEvent[$pevent]))\r
2616         {\r
2617             return $this->p_vars['event_stack']->popEvent();\r
2618         } else {\r
2619             return false;\r
2620         }\r
2621     }\r
2622 \r
2623     /**\r
2624      * setup the parser tokens, and the pushEvent/popEvent arrays\r
2625      * @see $tokens, $pushEvent, $popEvent\r
2626      */\r
2627     \r
2628     function setupStates()\r
2629     {\r
2630         $this->tokens[STATE_PHPCODE]            = array(" ", "\t",";","?>","</script>","/**#@+","/**#@-*/","/**", "//","/*","#","\r\n","\n","\r","(",'<<<','"',"'");\r
2631         $this->tokens[STATE_QUOTE]            = array("\\\"","\\\\","\"");\r
2632         $this->tokens[STATE_LOGICBLOCK]            = array("{","}","\"","'","/*","//","#","?>","</script>",'<<<','global','static');\r
2633         $this->tokens[STATE_FUNC_GLOBAL]        = array("\"","'","/*","//","#",";",",");\r
2634         $this->tokens[STATE_STATIC_VAR]        = array("\"","'","/*","//","#",";",",",'=','array');\r
2635         $this->tokens[STATE_STATIC_VAR_VALUE]        = array("/*","//","#"," ","\t",";","=","\"","'","array",",");\r
2636         $this->tokens[STATE_NOEVENTS]            = array("<?php","<?",'<script language="php">');\r
2637         $this->tokens[STATE_COMMENTBLOCK]        = array("*/","\n");\r
2638         $this->tokens[STATE_COMMENT]            = array("\r\n","\r","\n");\r
2639         $this->tokens[STATE_DEFINE]            = array(" ","(",";");\r
2640         $this->tokens[STATE_DEFINE_PARAMS]        = array("/*","//","#",",",")"," ","'","\"","(");\r
2641         $this->tokens[STATE_DEFINE_PARAMS_PARENTHESIS]    = array("(","'","\"",")");\r
2642         $this->tokens[STATE_FUNCTION_PARAMS]        = array("/*","//","#","\"",",",")","="," ","'","(");\r
2643         $this->tokens[STATE_SINGLEQUOTE]        = array("'","\\'","\\\\");\r
2644         $this->tokens[STATE_CLASS]            = array(" ", "\t", "?>", "</script>", ";", "}", "{",\r
2645                                                       "/**#@+", "/**#@-*/", "/**", "//", "/*", "#",\r
2646                                                       "\r\n", "\n", "\r","(");\r
2647         $this->tokens[STATE_DOCBLOCK]            = array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');\r
2648         $this->tokens[STATE_DOCBLOCK_TEMPLATE]            = array("*/","*","@","\r\n","\n","\r",". ",".\n",".\t",'{@');\r
2649         $this->tokens[STATE_DOCKEYWORD]            = array("@","*/","*","\n","\r\n","\r","\t"," ","<",">",'{@');\r
2650         $this->tokens[STATE_INLINE_DOCKEYWORD]        = array("{@","}","\t"," ","*/");\r
2651         $this->tokens[STATE_DOCKEYWORD_EMAIL]        = array(">","\n","\r\n","\r");\r
2652         $this->tokens[STATE_VAR]            = array("/*","//","#"," ","\t",";","=",",","\"","'","array");\r
2653         $this->tokens[STATE_GLOBAL]            = array("/*","//","#"," ","\t",";","=","\"","'");\r
2654         $this->tokens[STATE_GLOBAL_VALUE]            = array("/*","//","#"," ","\t",";","=","\"","'","array");\r
2655         $this->tokens[STATE_ARRAY]            = array("/*","//","#","(",")","\"","'","array");\r
2656         $this->tokens[STATE_FUNCTION]            = array("(","{","}"," ","\t","&","/*","//","#");\r
2657         $this->tokens[STATE_OUTPHP]            = array("<?php","<?",'<script language="php">');\r
2658         $this->tokens[STATE_EOFQUOTE]            = array(" ","\t","\n");\r
2659         $this->tokens[STATE_ESCAPE]            = false;// this tells the word parser to just cycle\r
2660         $this->tokens[STATE_INCLUDE]            = array(" ","(",";","'",'"');\r
2661         $this->tokens[STATE_INCLUDE_PARAMS]        = array("/*",")"," ","'","\"","(");\r
2662         $this->tokens[STATE_INCLUDE_PARAMS_PARENTHESIS]    = array("(","'","\"",")");\r
2663 \r
2664         // For each event word to event mapings\r
2665         $this->pushEvent[PARSER_EVENT_QUOTE] = \r
2666             array(\r
2667                 "\\"    => PARSER_EVENT_ESCAPE\r
2668             );\r
2669         $this->popEvent[PARSER_EVENT_QUOTE] = array("\"");\r
2670 ##########################\r
2671          \r
2672         $this->pushEvent[PARSER_EVENT_LOGICBLOCK] = \r
2673             array(\r
2674                 "\""    => PARSER_EVENT_QUOTE,\r
2675                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2676                 "//"     => PARSER_EVENT_COMMENT,\r
2677                 "#"     => PARSER_EVENT_COMMENT,\r
2678                 "global"    => PARSER_EVENT_FUNC_GLOBAL,\r
2679                 "static"    => PARSER_EVENT_STATIC_VAR,\r
2680                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2681                 "{"    => PARSER_EVENT_LOGICBLOCK,\r
2682                 "?>"    => PARSER_EVENT_OUTPHP,\r
2683                 "</script>"    => PARSER_EVENT_OUTPHP,\r
2684                 "<<<"    => PARSER_EVENT_EOFQUOTE\r
2685             );\r
2686         $this->popEvent[PARSER_EVENT_LOGICBLOCK] = array("}");\r
2687 ##########################\r
2688 \r
2689         $this->pushEvent[PARSER_EVENT_FUNC_GLOBAL] =\r
2690             array(\r
2691                 "\""    => PARSER_EVENT_QUOTE,\r
2692                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2693                 "//"     => PARSER_EVENT_COMMENT,\r
2694                 "#"     => PARSER_EVENT_COMMENT,\r
2695                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2696             );\r
2697         $this->popEvent[PARSER_EVENT_FUNC_GLOBAL] = array(";");\r
2698 ##########################\r
2699 \r
2700         $this->pushEvent[PARSER_EVENT_STATIC_VAR] =\r
2701             array(\r
2702                 "\""    => PARSER_EVENT_QUOTE,\r
2703                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2704                 "//"     => PARSER_EVENT_COMMENT,\r
2705                 "#"     => PARSER_EVENT_COMMENT,\r
2706                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2707                 "="        => PARSER_EVENT_STATIC_VAR_VALUE,\r
2708             );\r
2709         $this->popEvent[PARSER_EVENT_STATIC_VAR] = array(";");\r
2710 ##########################\r
2711 \r
2712         $this->pushEvent[PARSER_EVENT_STATIC_VAR_VALUE] = \r
2713             array(\r
2714                 "\""    => PARSER_EVENT_QUOTE,\r
2715                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2716                 "array" => PARSER_EVENT_ARRAY,\r
2717                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2718                 "//"     => PARSER_EVENT_COMMENT,\r
2719                 "#"     => PARSER_EVENT_COMMENT\r
2720             );\r
2721         $this->popEvent[PARSER_EVENT_STATIC_VAR_VALUE] = array(";",",");\r
2722 ##########################\r
2723 \r
2724         $this->pushEvent[PARSER_EVENT_NOEVENTS] = \r
2725             array(\r
2726                 "<?php" => PARSER_EVENT_PHPCODE,\r
2727                 "<?" => PARSER_EVENT_PHPCODE,\r
2728                 '<script language="php">' => PARSER_EVENT_PHPCODE,\r
2729             );\r
2730 ##########################\r
2731 \r
2732         $this->pushEvent[PARSER_EVENT_PHPCODE] = \r
2733             array(\r
2734                 "function"     => PARSER_EVENT_FUNCTION,\r
2735                 "class"     => PARSER_EVENT_CLASS,\r
2736                 "define"     => PARSER_EVENT_DEFINE,\r
2737                 "include_once" => PARSER_EVENT_INCLUDE,\r
2738                 "require_once" => PARSER_EVENT_INCLUDE,\r
2739                 "include"    => PARSER_EVENT_INCLUDE,\r
2740                 "require"    => PARSER_EVENT_INCLUDE,\r
2741                 "//"         => PARSER_EVENT_COMMENT,\r
2742                 "#"         => PARSER_EVENT_COMMENT,\r
2743                 "/*"         => PARSER_EVENT_COMMENTBLOCK,\r
2744                 "/**"         => PARSER_EVENT_DOCBLOCK,\r
2745                 "/**#@+"    => PARSER_EVENT_DOCBLOCK_TEMPLATE,\r
2746                 "/**#@-*/"    => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,\r
2747                 "\""        => PARSER_EVENT_QUOTE,\r
2748                 "'"        => PARSER_EVENT_SINGLEQUOTE,\r
2749                 "<<<"        => PARSER_EVENT_EOFQUOTE,\r
2750                 "?>"         => PARSER_EVENT_OUTPHP,\r
2751                 "</script>"         => PARSER_EVENT_OUTPHP,\r
2752             );\r
2753 ##########################\r
2754 \r
2755         $this->pushEvent[PARSER_EVENT_FUNCTION] = \r
2756             array(\r
2757                 "("     => PARSER_EVENT_FUNCTION_PARAMS,\r
2758                 "//"     => PARSER_EVENT_COMMENT,\r
2759                 "#"     => PARSER_EVENT_COMMENT,\r
2760                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2761                 "{"     => PARSER_EVENT_LOGICBLOCK\r
2762             );\r
2763         $this->popEvent[PARSER_EVENT_FUNCTION] = array("}");\r
2764 ##########################\r
2765 \r
2766         $this->pushEvent[PARSER_EVENT_DOCBLOCK] = \r
2767             array(\r
2768                 "@"     => PARSER_EVENT_DOCKEYWORD,\r
2769                 "{@"    => PARSER_EVENT_INLINE_DOCKEYWORD\r
2770             );\r
2771         $this->popEvent[PARSER_EVENT_DOCBLOCK] = array("*/");\r
2772 ##########################\r
2773 \r
2774         $this->pushEvent[PARSER_EVENT_DOCBLOCK_TEMPLATE] = \r
2775             array(\r
2776                 "@"     => PARSER_EVENT_DOCKEYWORD,\r
2777                 "{@"    => PARSER_EVENT_INLINE_DOCKEYWORD\r
2778             );\r
2779         $this->popEvent[PARSER_EVENT_DOCBLOCK_TEMPLATE] = array("*/");\r
2780 ##########################\r
2781 \r
2782         $this->pushEvent[PARSER_EVENT_CLASS] = \r
2783             array(\r
2784                 "function"     => PARSER_EVENT_FUNCTION,\r
2785                 "var"         => PARSER_EVENT_VAR,\r
2786                 "/**"         => PARSER_EVENT_DOCBLOCK,\r
2787                 "/**#@+"    => PARSER_EVENT_DOCBLOCK_TEMPLATE,\r
2788                 "/**#@-*/"    => PARSER_EVENT_END_DOCBLOCK_TEMPLATE,\r
2789                 "//"         => PARSER_EVENT_COMMENT,\r
2790                 "/*"         => PARSER_EVENT_COMMENTBLOCK,\r
2791                 "#"         => PARSER_EVENT_COMMENT,\r
2792                 "?>"        => PARSER_EVENT_OUTPHP,\r
2793                 "</script>"    => PARSER_EVENT_OUTPHP,\r
2794             );\r
2795         $this->popEvent[PARSER_EVENT_CLASS] = array("}");\r
2796 ##########################\r
2797 \r
2798         $this->pushEvent[PARSER_EVENT_DEFINE] = \r
2799             array(\r
2800                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2801                 "("     => PARSER_EVENT_DEFINE_PARAMS\r
2802             );\r
2803         $this->popEvent[PARSER_EVENT_DEFINE] = array(";");\r
2804 ##########################\r
2805 \r
2806         $this->pushEvent[PARSER_EVENT_INCLUDE] = \r
2807             array(\r
2808                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2809                 "("     => PARSER_EVENT_INCLUDE_PARAMS,\r
2810                 "'"        => PARSER_EVENT_SINGLEQUOTE,\r
2811                 '"'        => PARSER_EVENT_QUOTE,\r
2812             );\r
2813         $this->popEvent[PARSER_EVENT_INCLUDE] = array(";");\r
2814 ##########################\r
2815 \r
2816         $this->pushEvent[PARSER_EVENT_DEFINE_PARAMS] = \r
2817             array(\r
2818                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,\r
2819                 "'"        => PARSER_EVENT_SINGLEQUOTE,\r
2820                 '"' =>    PARSER_EVENT_QUOTE,\r
2821                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2822                 "//"     => PARSER_EVENT_COMMENT,\r
2823                 "#"     => PARSER_EVENT_COMMENT\r
2824             );\r
2825         $this->popEvent[PARSER_EVENT_DEFINE_PARAMS] = array(")");\r
2826 ##########################\r
2827 \r
2828         $this->pushEvent[PARSER_EVENT_INCLUDE_PARAMS] = \r
2829             array(\r
2830                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,\r
2831                 "'" =>    PARSER_EVENT_SINGLEQUOTE,\r
2832                 '"' =>    PARSER_EVENT_QUOTE,\r
2833             );\r
2834         $this->popEvent[PARSER_EVENT_INCLUDE_PARAMS] = array(")");\r
2835 ##########################\r
2836 \r
2837         $this->pushEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] =\r
2838             array(\r
2839                 "("    =>    PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS,\r
2840                 "'" =>    PARSER_EVENT_SINGLEQUOTE,\r
2841                 '"' =>    PARSER_EVENT_QUOTE,\r
2842             );\r
2843         $this->popEvent[PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS] = array(")");\r
2844 ##########################\r
2845 \r
2846         $this->pushEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] =\r
2847             array(\r
2848                 "("    =>    PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS,\r
2849                 "'" =>    PARSER_EVENT_SINGLEQUOTE,\r
2850                 '"' =>    PARSER_EVENT_QUOTE,\r
2851             );\r
2852         $this->popEvent[PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS] = array(")");\r
2853 ##########################\r
2854 \r
2855         $this->pushEvent[PARSER_EVENT_VAR] = \r
2856             array(\r
2857                 "\""    => PARSER_EVENT_QUOTE,\r
2858                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2859                 "array" => PARSER_EVENT_ARRAY,\r
2860                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2861                 "//"     => PARSER_EVENT_COMMENT,\r
2862                 "#"     => PARSER_EVENT_COMMENT\r
2863             );\r
2864         $this->popEvent[PARSER_EVENT_VAR] = array(";");\r
2865 ##########################\r
2866 \r
2867         $this->pushEvent[PARSER_EVENT_DEFINE_GLOBAL] = \r
2868             array(\r
2869                 "="    => PARSER_EVENT_GLOBAL_VALUE,\r
2870                 "\""    => PARSER_EVENT_QUOTE,\r
2871                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2872                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2873                 "//"     => PARSER_EVENT_COMMENT,\r
2874                 "#"     => PARSER_EVENT_COMMENT\r
2875             );\r
2876         $this->popEvent[PARSER_EVENT_DEFINE_GLOBAL] = array(";");\r
2877 ##########################\r
2878 \r
2879         $this->pushEvent[PARSER_EVENT_GLOBAL_VALUE] = \r
2880             array(\r
2881                 "\""    => PARSER_EVENT_QUOTE,\r
2882                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2883                 "array" => PARSER_EVENT_ARRAY,\r
2884                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2885                 "//"     => PARSER_EVENT_COMMENT,\r
2886                 "#"     => PARSER_EVENT_COMMENT\r
2887             );\r
2888         $this->popEvent[PARSER_EVENT_GLOBAL_VALUE] = array(";");\r
2889 ##########################\r
2890 \r
2891         $this->pushEvent[PARSER_EVENT_COMMENT] = \r
2892             array(\r
2893                 "\\"    => PARSER_EVENT_ESCAPE\r
2894             );\r
2895         $this->popEvent[PARSER_EVENT_COMMENT] = array("\n");\r
2896 ##########################\r
2897 \r
2898         $this->popEvent[PARSER_EVENT_COMMENTBLOCK] = array("*/");\r
2899 ##########################\r
2900         $this->pushEvent[PARSER_EVENT_SINGLEQUOTE] = \r
2901             array(\r
2902                 "\\"    => PARSER_EVENT_ESCAPE\r
2903             );\r
2904 \r
2905         $this->popEvent[PARSER_EVENT_SINGLEQUOTE] = array("'");\r
2906 ##########################\r
2907         $this->pushEvent[PARSER_EVENT_FUNCTION_PARAMS] = \r
2908             array(\r
2909                 "\""    => PARSER_EVENT_QUOTE,\r
2910                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2911                 "array" => PARSER_EVENT_ARRAY,\r
2912                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2913                 "//"     => PARSER_EVENT_COMMENT,\r
2914                 "#"     => PARSER_EVENT_COMMENT\r
2915             );\r
2916         $this->popEvent[PARSER_EVENT_FUNCTION_PARAMS] = array(")");\r
2917 ##########################\r
2918         $this->pushEvent[PARSER_EVENT_DOCKEYWORD] = \r
2919             array(\r
2920 //                "<"    => PARSER_EVENT_DOCKEYWORD_EMAIL,\r
2921                 "{@" => PARSER_EVENT_INLINE_DOCKEYWORD,\r
2922             );\r
2923 \r
2924         $this->popEvent[PARSER_EVENT_DOCKEYWORD] = array("*/");\r
2925 ##########################\r
2926 \r
2927         $this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORD] = array("}","*/");\r
2928 ##########################\r
2929 \r
2930         $this->popEvent[PARSER_EVENT_OUTPHP] = array("<?php","<?",'<script language="php">');\r
2931 ##########################\r
2932 \r
2933         $this->popEvent[PARSER_EVENT_DOCKEYWORD_EMAIL] = array(">","\n");\r
2934 \r
2935 ##########################\r
2936         $this->pushEvent[PARSER_EVENT_ARRAY] = \r
2937             array(\r
2938                 "\""    => PARSER_EVENT_QUOTE,\r
2939                 "'"    => PARSER_EVENT_SINGLEQUOTE,\r
2940                 "array" => PARSER_EVENT_ARRAY,\r
2941                 "/*"     => PARSER_EVENT_COMMENTBLOCK,\r
2942                 "//"     => PARSER_EVENT_COMMENT,\r
2943                 "#"     => PARSER_EVENT_COMMENT\r
2944             );\r
2945         $this->popEvent[PARSER_EVENT_ARRAY] = array(")");\r
2946 ##########################\r
2947     }\r
2948 \r
2949     /**\r
2950      * tell the parser's WordParser {@link $wp} to set up tokens to parse words by.\r
2951      * tokens are word separators.  In English, a space or punctuation are examples of tokens.\r
2952      * In PHP, a token can be a ;, a parenthesis, or even the word "function"\r
2953      * @param    $value integer an event number\r
2954      * @see WordParser\r
2955      */\r
2956     \r
2957     function configWordParser($e)\r
2958     {\r
2959         $this->wp->setSeperator($this->tokens[($e + 100)]);\r
2960     }\r
2961 \r
2962     /**\r
2963      * Debugging function, takes an event number and attempts to return its name\r
2964      * @param    $value integer an event number\r
2965      */\r
2966     \r
2967 \r
2968     function getParserEventName ($value)\r
2969     {    \r
2970         $lookup = array(\r
2971             PARSER_EVENT_NOEVENTS         => "PARSER_EVENT_NOEVENTS",\r
2972             PARSER_EVENT_PHPCODE        => "PARSER_EVENT_PHPCODE",\r
2973             PARSER_EVENT_DOCBLOCK        => "PARSER_EVENT_DOCBLOCK",\r
2974             PARSER_EVENT_FUNCTION        => "PARSER_EVENT_FUNCTION",\r
2975             PARSER_EVENT_CLASS        => "PARSER_EVENT_CLASS",\r
2976             PARSER_EVENT_DEFINE        => "PARSER_EVENT_DEFINE",\r
2977             PARSER_EVENT_DEFINE_PARAMS    => "PARSER_EVENT_DEFINE_PARAMS",\r
2978             PARSER_EVENT_COMMENT        => "PARSER_EVENT_COMMENT",\r
2979             PARSER_EVENT_COMMENTBLOCK    => "PARSER_EVENT_COMMENTBLOCK",\r
2980             PARSER_EVENT_ESCAPE        => "PARSER_EVENT_ESCAPE",\r
2981             PARSER_EVENT_QUOTE        => "PARSER_EVENT_QUOTE",\r
2982             PARSER_EVENT_FUNCTION_PARAMS    => "PARSER_EVENT_FUNCTION_PARAMS",\r
2983             PARSER_EVENT_SINGLEQUOTE    => "PARSER_EVENT_SINGLEQUOTE",\r
2984             PARSER_EVENT_VAR        => "PARSER_EVENT_VAR",\r
2985             PARSER_EVENT_LOGICBLOCK        => "PARSER_EVENT_LOGICBLOCK",\r
2986             PARSER_EVENT_OUTPHP        => "PARSER_EVENT_OUTPHP",\r
2987             PARSER_EVENT_DOCKEYWORD        => "PARSER_EVENT_DOCKEYWORD",\r
2988             PARSER_EVENT_DOCKEYWORD_EMAIL    => "PARSER_EVENT_DOCKEYWORD_EMAIL",\r
2989             PARSER_EVENT_ARRAY        => "PARSER_EVENT_ARRAY",\r
2990             PARSER_EVENT_INLINE_DOCKEYWORD    =>    "PARSER_EVENT_INLINE_DOCKEYWORD",\r
2991             PARSER_EVENT_EOFQUOTE    =>    "PARSER_EVENT_EOFQUOTE",\r
2992             PARSER_EVENT_INCLUDE    =>    "PARSER_EVENT_INCLUDE",\r
2993             PARSER_EVENT_INCLUDE_PARAMS    =>    "PARSER_EVENT_INCLUDE_PARAMS",\r
2994             PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS    => "PARSER_EVENT_INCLUDE_PARAMS_PARENTHESIS",\r
2995             PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS => "PARSER_EVENT_DEFINE_PARAMS_PARENTHESIS",\r
2996             PARSER_EVENT_DEFINE_GLOBAL => "PARSER_EVENT_DEFINE_GLOBAL",\r
2997             PARSER_EVENT_GLOBAL_VALUE => "PARSER_EVENT_GLOBAL_VALUE",\r
2998             PARSER_EVENT_FUNC_GLOBAL => "PARSER_EVENT_FUNC_GLOBAL",\r
2999             PARSER_EVENT_STATIC_VAR => "PARSER_EVENT_STATIC_VAR",\r
3000             PARSER_EVENT_DOCBLOCK_TEMPLATE => "PARSER_EVENT_DOCBLOCK_TEMPLATE",\r
3001             PARSER_EVENT_END_DOCBLOCK_TEMPLATE => "PARSER_EVENT_END_DOCBLOCK_TEMPLATE",\r
3002             PARSER_EVENT_METHOD_LOGICBLOCK => 'PARSER_EVENT_METHOD_LOGICBLOCK',\r
3003             PARSER_EVENT_CLASS_MEMBER => 'PARSER_EVENT_CLASS_MEMBER',\r
3004             PARSER_EVENT_METHOD => 'PARSER_EVENT_METHOD',\r
3005             PARSER_EVENT_QUOTE_VAR => 'PARSER_EVENT_QUOTE_VAR',\r
3006             PARSER_EVENT_ACCESS_MODIFIER => 'PARSER_EVENT_ACCESS_MODIFIER',\r
3007             PARSER_EVENT_IMPLEMENTS => 'PARSER_EVENT_IMPLEMENTS',\r
3008             PARSER_EVENT_CLASS_CONSTANT => 'PARSER_EVENT_CLASS_CONSTANT',\r
3009             PARSER_EVENT_VAR_ARRAY => 'PARSER_EVENT_VAR_ARRAY',\r
3010             PARSER_EVENT_VAR_ARRAY_COMMENT =>'PARSER_EVENT_VAR_ARRAY_COMMENT',\r
3011         );\r
3012         if (isset($lookup[$value]))\r
3013         return $lookup[$value];\r
3014         else return $value;\r
3015     }\r
3016 }\r
3017 \r
3018 /**\r
3019  * Global package page parser\r
3020  *\r
3021  * @deprecated in favor of tutorials\r
3022  * @tutorial tutorials.pkg\r
3023  * @package phpDocumentor\r
3024  * @subpackage Parsers\r
3025  */\r
3026 class ppageParser extends Parser\r
3027 {\r
3028     /** @var string */\r
3029     var $package = false;\r
3030     /** @var string */\r
3031     var $subpackage = '';\r
3032     /**\r
3033      * set up invariant Parser variables\r
3034      */\r
3035     function ppageParser()\r
3036     {\r
3037         Parser::Parser();\r
3038         $this->allowableInlineTags = $GLOBALS['_phpDocumentor_inline_tutorial_tags_allowed'];\r
3039         $this->eventHandlers = array();\r
3040         $this->eventHandlers[PARSER_EVENT_NOEVENTS] = 'defaultHandler';\r
3041         $this->eventHandlers[PARSER_EVENT_INLINE_DOCKEYWORD] = 'handleInlineDocKeyword';\r
3042     }\r
3043     \r
3044     /**\r
3045      * set up invariant Parser variables\r
3046      */\r
3047     function setupStates()\r
3048     {\r
3049         $this->tokens[STATE_NOEVENTS]        = array("{@","}");\r
3050         $this->tokens[STATE_INLINE_DOCKEYWORD]        = array("{@","}","\t"," ");\r
3051 \r
3052 ##########################\r
3053 \r
3054         $this->pushEvent[PARSER_EVENT_NOEVENTS] = \r
3055             array(\r
3056                 "{@" => PARSER_EVENT_INLINE_DOCKEYWORD\r
3057             );\r
3058 ##########################\r
3059 \r
3060         $this->popEvent[PARSER_EVENT_INLINE_DOCKEYWORD] = array("}");\r
3061     }\r
3062     \r
3063     /**\r
3064      * Parse a new file\r
3065      *\r
3066      * @param    string    $parse_data\r
3067      * @param    string    $package\r
3068      * @param    int    $subpackage\r
3069      * @return    mixed    false or parsed data\r
3070      */\r
3071     function parse (&$parse_data,$xml,$package = 'default',$subpackage = '',$tutorial = '',\r
3072                     $category='default', $path='')\r
3073     {\r
3074         $this->setupStates();\r
3075         $this->p_vars['total'] = new parserPackagePage($package,$xml);\r
3076         $this->p_vars['tutorial'] = $tutorial;\r
3077         $this->_path = $path;\r
3078         $this->category = $category;\r
3079         $this->package = $package;\r
3080         if (!isset($subpackage) || !$subpackage) $subpackage = '';\r
3081         $this->subpackage = $subpackage;\r
3082         if (strlen($parse_data) == 0)\r
3083         {\r
3084             return false;\r
3085         }\r
3086 \r
3087         // initialize variables so E_ALL error_reporting doesn't complain\r
3088         $pevent = 0;\r
3089         $word = 0;\r
3090         $this->p_vars['event_stack'] = new EventStack;\r
3091         // change this to a new ParserStringWithInlineTags, and change all $total .= blah to $total->add(blah)\r
3092         // then modify phpDocumentor_IntermediateParser->Convert to convert all package pages (the package page handler in phpDocumentor_IntermediateParser should\r
3093         // save them all in a variable) to perform the linking.  then, remove the legacy code from handleDocBlock\r
3094         // and handleClass in Render.inc, and do a loop that converts each package page, and passes it to handleEvent\r
3095         // just like Converter::walk does with the other elements.  The only other addition that might be good is a\r
3096         // new descendant of parserElement parserPackagePage that contains the data and stuff.  Hope this helps :)\r
3097         $total = '';\r
3098 \r
3099         $this->wp->setup($parse_data);\r
3100 \r
3101         $this->p_flags['reset_quote_data'] = true;\r
3102 \r
3103         do\r
3104         {\r
3105             $lpevent = $pevent;\r
3106             $pevent = $this->p_vars['event_stack']->getEvent();\r
3107             if ($lpevent != $pevent)\r
3108             {\r
3109                 $this->p_vars['last_pevent'] = $lpevent;\r
3110             }\r
3111 \r
3112             if ($this->p_vars['last_pevent'] != $pevent)\r
3113             {\r
3114                 // its a new event so the word parser needs to be reconfigured \r
3115                 $this->configWordParser($pevent);\r
3116             }\r
3117 \r
3118             if (!$xml)\r
3119             $this->publishEvent(PHPDOCUMENTOR_EVENT_NEWSTATE,($pevent + 100));\r
3120 \r
3121 \r
3122             $this->p_vars['last_word'] = $word;\r
3123             $word = $this->wp->getWord();\r
3124 \r
3125             if (PHPDOCUMENTOR_DEBUG == true)\r
3126             {\r
3127                 echo "LAST: |" . $this->p_vars['last_word'] . "|\n";\r
3128                 echo "PEVENT: " . $this->getParserEventName($pevent) . "\n";\r
3129                 echo $this->wp->getPos() . ": |$word|\n";\r
3130             }\r
3131             if (isset($this->eventHandlers[$pevent]))\r
3132             {\r
3133                 $handle = $this->eventHandlers[$pevent];\r
3134                 $this->$handle($word, $pevent);\r
3135             }\r
3136         } while (!($word === false));\r
3137         if (!$xml)\r
3138         $this->PublishEvent(PHPDOCUMENTOR_EVENT_PACKAGEPAGE,$this->p_vars['total']);\r
3139         else\r
3140         return $this->p_vars['total']->value;\r
3141     }\r
3142     \r
3143     /**\r
3144      * Handles all non-inline tags\r
3145      * \r
3146      * @param string token\r
3147      * @param integer parser event\r
3148      */\r
3149     function defaultHandler($word, $pevent)\r
3150     {\r
3151         if (!$this->checkEventPush( $word, $pevent))\r
3152         {\r
3153             if ($word) $this->p_vars['total']->add($word);\r
3154         }\r
3155     }\r
3156 \r
3157     /**\r
3158      * handler for INLINE_DOCKEYWORD.\r
3159      * this handler recognizes {@inline tags} like link, and parses them, replacing them directly\r
3160      * in the text flow with their output.\r
3161      * @param string token\r
3162      * @param integer parser event\r
3163      */\r
3164     \r
3165     function handleInlineDockeyword($word, $pevent)\r
3166     {\r
3167         //        echo $this->wp->getPos() . ": |$word|\n";\r
3168 \r
3169         //        echo "docktype: $this->p_vars['inline_dockeyword_type']\n";\r
3170         if (!isset($this->p_vars['inline_dockeyword_type'])) $this->p_vars['inline_dockeyword_type'] = false;\r
3171         if (!isset($this->p_vars['inline_dockeyword_data'])) $this->p_vars['inline_dockeyword_data'] = '';\r
3172         if (!$this->p_vars['inline_dockeyword_type'])\r
3173         {\r
3174             if (in_array($word,$this->allowableInlineTags))\r
3175             {\r
3176                 $this->p_vars['inline_dockeyword_type'] = strtolower($word);\r
3177                 $this->p_vars['whitesp'] = $this->wp->returnWhiteSpace;\r
3178                 $this->wp->setWhiteSpace(true);\r
3179             } else {\r
3180                 if ($word == '}')\r
3181                 $this->p_vars['total']->add('{@');\r
3182                 else\r
3183                 {\r
3184                     $this->p_vars['total']->add('{@'.$word);\r
3185                     $this->p_vars['event_stack']->popEvent();\r
3186                 }\r
3187                 $this->p_vars['inline_dockeyword_type'] = false;\r
3188                 $this->p_vars['inline_dockeyword_data'] = '';\r
3189             }\r
3190         } else\r
3191         {\r
3192             if ($word != "}")\r
3193             {\r
3194                 $this->p_vars['inline_dockeyword_data'] .= $word;\r
3195             }\r
3196         }\r
3197         if ($this->checkEventPop($word,$pevent))\r
3198         {\r
3199             $this->wp->setWhiteSpace($this->p_vars['whitesp']);\r
3200             if ($this->p_vars['inline_dockeyword_type']=='link')\r
3201             {\r
3202                 // support hyperlinks of any protocol\r
3203                 if (is_numeric(strpos($this->p_vars['inline_dockeyword_data'],'://')) || (strpos(trim($this->p_vars['inline_dockeyword_data']),'mailto:') === 0))\r
3204                 {\r
3205                     // if there is more than 1 parameter, the stuff after the space is the hyperlink text\r
3206                     if (strpos(trim($this->p_vars['inline_dockeyword_data']),' '))\r
3207                     {\r
3208                         $i1 = strpos(trim($this->p_vars['inline_dockeyword_data']),' ') + 1;\r
3209                         $link = substr(trim($this->p_vars['inline_dockeyword_data']),0,$i1 - 1);\r
3210                         $text = substr(trim($this->p_vars['inline_dockeyword_data']),$i1);\r
3211                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($link,$text);\r
3212 //                        '<a href="'.$link.'">'.$text.'</a>';\r
3213                     }\r
3214                     else\r
3215                     {\r
3216                         $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
3217                     }\r
3218 //                    '<a href="'.$this->p_vars['inline_dockeyword_data'].'">'.$this->p_vars['inline_dockeyword_data'].'</a>';\r
3219                 } else\r
3220                 {\r
3221                     $testp = explode('#',$this->p_vars['inline_dockeyword_data']);\r
3222                     if (count($testp) - 1) $this->p_vars['inline_dockeyword_data'] = $testp[1];\r
3223                     $this->p_vars['inline_dockeyword_data'] = new parserLinkInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
3224                 }\r
3225             }\r
3226             if ($this->p_vars['inline_dockeyword_type']=='id')\r
3227             {\r
3228                 $this->p_vars['inline_dockeyword_data'] = new parserIdInlineTag($this->category,$this->package,$this->subpackage,$this->p_vars['tutorial'],trim($this->p_vars['inline_dockeyword_data']));\r
3229             }\r
3230             if ($this->p_vars['inline_dockeyword_type'] == 'tutorial')\r
3231             {\r
3232                 $this->p_vars['inline_dockeyword_data'] = new parserTutorialInlineTag($this->p_vars['inline_dockeyword_data'],$this->p_vars['inline_dockeyword_data']);\r
3233             }\r
3234             if ($this->p_vars['inline_dockeyword_type'] == 'toc')\r
3235             {\r
3236                 $this->p_vars['inline_dockeyword_data'] = new parserTocInlineTag();\r
3237             }\r
3238             if ($this->p_vars['inline_dockeyword_type'] == 'example')\r
3239             {\r
3240                 $example =\r
3241                     new parserExampleInlineTag($this->p_vars['inline_dockeyword_data'], $this->_path, true);\r
3242                 $this->p_vars['total']->add($example->getProgramListing());\r
3243             } else\r
3244             {\r
3245                 $this->p_vars['total']->add($this->p_vars['inline_dockeyword_data']);\r
3246             }\r
3247             $this->p_vars['inline_dockeyword_type'] = false;\r
3248             $this->p_vars['inline_dockeyword_data'] = '';\r
3249         }\r
3250     }\r
3251 }\r
3252 ?>\r