Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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