!C99Shell v. 1.0 pre-release build #13!

Software: Apache. PHP/5.5.15 

uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 

SYSTEM 

Safe-mode: OFF (not secure)

C:\dmz\php\pear\PhpDocumentor\phpDocumentor\   drwxrwxrwx
Free 4.1 GB of 39.52 GB (10.37%)
Detected drives: [ a ] [ c ] [ d ] [ e ] [ f ]
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     IntermediateParser.inc (75.98 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * The phpDocumentor_IntermediateParser Class
 *
 * The Intermediary Data Parser (intermediate between Parse and Converter)
 *
 * phpDocumentor :: automatic documentation generator
 *
 * PHP versions 4 and 5
 *
 * Copyright (c) 2002-2006 Gregory Beaver
 *
 * LICENSE:
 *
 * This library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any
 * later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package    phpDocumentor
 * @author     Gregory Beaver <cellog@php.net>
 * @copyright  2002-2006 Gregory Beaver
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @version    CVS: $Id: IntermediateParser.inc 317234 2011-09-24 05:03:55Z ashnazg $
 * @filesource
 * @link       http://www.phpdoc.org
 * @link       http://pear.php.net/PhpDocumentor
 * @since      1.1
 */
/** The phpDocumentor_IntermediateParser Class
 *
 * This class performs the work of organizing raw data from the parser in the
 * format of descendants of the {@link parserElement} class.  This is also where
 * processing of package pages occurs, in
 * {@link phpDocumentor_IntermediateParser::handleClass()} for class-level
 * packages and {@link phpDocumentor_IntermediateParser::handleDocBlock()} for
 * page-level packages.
 *
 * Most of the work of this parser goes to matching up
 * DocBlocks with the elements that they are documenting.  Since DocBlocks are
 * passed before the element they document, the last DocBlock is stored in
 * {@link phpDocumentor_IntermediateParser::$last} and then placed into the
 * $docblock parameter of the parserElement
 * descendant object.
 *  @author Gregory Beaver
 *  @version $Id: IntermediateParser.inc 317234 2011-09-24 05:03:55Z ashnazg $
 *  @copyright 2002 Gregory Beaver
 *  @package     phpDocumentor
 */
class phpDocumentor_IntermediateParser
{
    
/**
     * @var parserDocBlock
     */
    
var $last;

    
/**
     * type of the last parser Element handled
     *
     * This is used in handleDocBlock to determine whether a DocBlock is a
     * page-level DocBlock in conjunction with the {@link parserData::$clean}
     * var.  A page-level DocBlock is alwaysthe first DocBlock in a file, and
     * must be followed by another DocBlock.  The first test is handled by
     * parserData::$clean, which is set to false on the first encounter of an
     * element, and the second test is handled by this variable, which must be
     * equal to "docblock"
     * @see handleDocBlock()
     * @var string
     */
    
var $lasttype '';

    
/**
     * Name of the class currently being parsed.
     * It is only used (and only valid) when phpDocumentor_IntermediateParser is
     * parsing a class
     * @var string
     */
    
var $cur_class '';

    
/**
     * type of the current parser Element being handled
     *
     * This is used by {@link HandleEvent()} to set the {@link $lasttype} var,
     * which is used to detect page-level DocBlocks
     * @var string
     */
    
var $type '';

    
/**
     * set in {@link Setup.inc.php} to the value of the parseprivate commandline
     * option.  If this option is true, elements with an @access private tag
     * will be parsed and displayed
     * @tutorial phpDocumentor.howto.pkg#using.command-line.parseprivate
     * @var boolean
     */
    
var $parsePrivate false;

    
/**
     * this variable is used to prevent parsing of elements with an @ignore tag
     * @see $packageoutput
     * @see $parsePrivate
     */
    
var $private_class false;

    
/**
     * used to set the output directory
     * @see setTargetDir()
     */
    
var $targetDir;

    
/**
     * used to set the template base directory
     * @see setTemplateBase()
     */
    
var $templateBase;

    
/**
     * array of parsed package pages
     *
     * used by {@link Convert()} to convert all package pages into output
     * @var array
     */
    
var $package_pages = array();

    
/**
     * @var array array of all {@link parserData} containing page information
     */
    
var $pages = array();
    
/**
     * Put away a page that has been @ignored or @access private if
     * !{@link $parsePrivate}
     *
     * When a page has @access private in its DocBlock, it is placed here
     * instead of in {@link $pages}, to allow for proper Class parsing.  Since
     * classes and pages are parsed as if they were separate, this array allows
     * public classes on private pages to retrieve information needed about the
     * page that holds the class and to {@link addPageIfNecessary()} to the
     * $pages array
     * @var array
     */
    
var $privatepages = array();
    
/**
     * Keeps track of packages of classes that have parent classes in another
     * package.  Used in automatic linking.
     *
     * This array is updated by {@link addPackageParent()}, which is called in
     * {@link Classes::processChild()} to keep track of classes that descend
     * from classes in different packages.  In other words, if class foo is in
     * package one, and class bar is in package two, an entry
     * $package_parents['two'] = 'one' will be made.
     * @var array Format: packagename => parentpackagename
     * @see Converter::getLink()
     */
    
var $package_parents = array();

    
/**
     * Used to determine the category for tutorials.
     *
     * <b>WARNING:</b> If more than one category exists, the last category
     * encountered will overwrite the previous and will raise a big warning
     * @var array Format: packagename => categoryname
     */
    
var $packagecategories = array();

    
/**
     * list of all packages encountered while documenting.  Used in automatic
     * linking.
     *
     * Converter::getLink() first checks if an ambiguous link is found in the
     * current package.  If not, it then checks in parent packages, and if still
     * not found, uses this array to check in the rest of the packages before
     * giving up
     * @var array Format: array(packagename => 1, packagename => 1,...)
     * @see Converter::getLink()
     */
    
var $all_packages = array();

    
/**
     * array of packages to parser and output documentation for, if not all
     * packages should be documented
     *
     * Format:<br />
     * array(package1,package2,...)<br />
     * or false if not set
     *
     * Use this option to limit output similar to ignoring files.  If you have
     * some temporary files that you don't want to specify by name but don't
     * want included in output, set a package name for all the elements in your
     * project, and set packageoutput to that name.  the default package will be
     * ignored.  Parsing speed does not improve.  If you want to ignore files
     * for speed reasons, use the ignore command-line option
     * @tutorial phpDocumentor.howto.pkg#using.command-line.packageoutput
     * @see Io
     * @var false|array
     */
    
var $packageoutput false;

    
/**
     * the functions which handle output from the {@link Parser}
     * @see handleEvent(), handleDocBlock(), handlePage(), handleClass()
     * @see handleDefine(), handleFunction(), handleMethod(), handleVar()
     * @see handlePackagePage(), handleInclude(), handleTutorial()
     */
    
var $event_handlers = array(
            
'docblock' => 'handleDocBlock',
            
'page' => 'handlePage',
            
'class' => 'handleClass',
            
'define' => 'handleDefine',
            
'function' => 'handleFunction',
            
'method' => 'handleMethod',
            
'var' => 'handleVar',
            
'const' => 'handleConst',
            
'packagepage' => 'handlePackagePage',
            
'include' => 'handleInclude',
            
'global' => 'handleGlobal',
            
'tutorial' => 'handleTutorial',
            );

    
/**
     * $data contains parsed structures for the current page being parsed
     *
     * In version 1.1+, $data is only used to store the current page information.
     * All handling of documented elements is handled by the
     * {@link ProceduralPages} and {@link Classes} classes.
     * @var parserData
     */
    
var $data;

    
/**
     * set in {@link Setup.inc.php} to the value of the quitemode commandline
     * option.
     *
     * If this option is true, informative output while parsing will not be
     * displayed (documentation is unaffected)
     * @var boolean
     * @tutorial phpDocumentor.howto.pkg#using.command-line.quiet
     */
    
var $quietMode false;

    
/**
     * set in {@link Setup.inc.php} to the value of the undocumentedElementWarnings commandline
     * option.
     *
     * If this option is true, warnings about certain elements (classes, methods)
     * that are not documented with DocBlocks will be shown while parsing,
     * and will also be displayed in the errors.html page
     * (other documentation is unaffected)
     * @var boolean
     * @tutorial phpDocumentor.howto.pkg#using.command-line.undocumentedelements
     */
    
var $undocumentedElementWarnings false;

    
/**
     * used to keep track of inheritance at the smartest level possible for a
     * dumb computer
     * @var Classes
     */
    
var $classes false;

    
/**
     * used to keep track of all elements in a procedural page.  Handles name
     * conflicts with elegance
     * @since 1.1
     * @var ProceduralPages
     */
    
var $proceduralpages false;

    
/**
     * an array of template names indexed by converter name
     *
     * For example, if the default HTMLframesConverter is using the DOM/l0l33t
     * template, the array will be
     * <code>$converters['frames'] = 'DOM/l0l33t'</code>
     * @var array Format: array(Convertername1 => templatename)
     * @see Converter
     */
    
var $converters false;
    
/**
     * @var string Title of generated documentation, passed to Converters
     */
    
var $title '';

    var 
$uses = array();

    var 
$db_template;

    
/**
     * Stores parsed CHANGELOG/INSTALL/README files
     * @var array Format: array(CHANGELOG => contents,
     *                          INSTALL => contents,
     *                          README => contents)
     */
    
var $ric = array();

    
/**
     * Flag used to determine whether the last docblock
     * was a page-level docblock.
     * @var boolean
     * @access private
     */
    
var $_lastDocBlockWasPageLevel false;

    
/**
     * Flag used to determine whether the Page-level
     * DocBlock was declared in old or new style
     * @var boolean
     * @access private
     */
    
var $_oldPageLevel false;

    
/**
     * sets up basic data structures
     * @param string Title of generated documentation, passed to Converters
     * @see $title, $data, $classes, $proceduralpages
     */
    
function phpDocumentor_IntermediateParser($title='Generated Documentation')
    {
        
$this->title $title;
        
$this->data = new parserData;
        
$this->classes = new Classes;
        
$this->proceduralpages = new ProceduralPages;
    }

    
/**
     * Retrieve the relative path.  If the path contains "pear/" it will
     * be used as the base, otherwise the Program_Root string will be used.
     * @global array uses 'Program_Root' option to replace it with '' for
     *               retrieving the source location of a file
     * @param string path to file
     * @return string
     * @see $sourceLocation
     * @access private
     */
    
function _getSourceLocation($sl$sourceloc)
    {
        global 
$_phpDocumentor_options;
        if (empty(
$sl)) return false;
        
$sl str_replace('\\','/',$sl);
        if (
strpos($sl,'pear/'))
        {
            
$sl substr($sl,strpos($sl,'pear/') + 5);
            if (
dirname($sl) == '.')
            {
                return 
'PEAR';
            }
            return 
dirname($sl);
        } else
        {
            if (
strpos(str_replace($_phpDocumentor_options['Program_Root'] . PATH_DELIMITER,'',$sourceloc),PATH_DELIMITER) === false)
                return 
'';
            return 
dirname(str_replace($_phpDocumentor_options['Program_Root'] . PATH_DELIMITER,'',$sourceloc));
        }
    }

    
/**
     * Guess the package/subpackage based on subdirectory if the --pear option
     *
     * A file in pear/dir/file.php will be in package "dir."  A file in
     * pear/dir/subdir/file.php will be in package "dir," subpackage "subdir."
     * @param string full path of file
     * @param template-ready source location Program_Root/dir/file.php
     * @global array uses the 'pear' option to determine whether to guess based
     *               on subdirectory
     * @tutorial phpDocumentor.howto.pkg#using.command-line.pear
     */
    
function _guessPackage($path$sourceloc)
    {
        global 
$_phpDocumentor_setting;
        if (isset(
$_phpDocumentor_setting['pear']) && $_phpDocumentor_setting['pear'])
        {
            
$subpath explode(PATH_DELIMITER$this->_getSourceLocation($path$sourceloc));
            if (!empty(
$subpath[0]))
            { 
// can only have package and subpackage in this version
                
$package $subpath[0];
                
$subpackage '';
                if (isset(
$subpath[1])) $subpackage $subpath[1];
                return array(
$package,$subpackage);
            } else return array(
$this->package$this->subpackage);
        } else return array(
$this->package$this->subpackage);
    }

    
/**
     * handles post-parsing of include/require/include_once/require_once
     *
     * This function sets {@link $data}->clean to false to tell the
     * phpDocumentor_IntermediateParser that a page-level DocBlock can't be
     * found after this point on this page.  It then sets the package
     * to be the same as the page, and adds itself to the
     * {@link ProceduralPages} class
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserInclude $data
     */
    
function handleInclude($event,$data)
    {
        if (
$this->_lastDocBlockWasPageLevel)
        {
            
addWarning(PDERROR_DOCBLOCK_CONFLICT$data->getName(), $data->getValue());
            if (!
$this->_oldPageLevel)
            {
                unset(
$this->last);
            }
        }
        
$this->_lastDocBlockWasPageLevel false;
        
$this->data->clean false;
        
// page was @ignored
        
if ($this->private_page)
        {
            unset(
$this->last);
            return;
        }
        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
if ($this->last->getKeyword('ignore'))
        {
            
$this->last false;
            return;
//            addWarning(PDERROR_IGNORE_TAG_IGNORED,'include',$data->getName().'('.$data->getValue().')');
        
}

        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'include');
        
$data->setDocBlock($this->last);
        
$this->proceduralpages->addInclude($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of global variables
     *
     * This function sets {@link $data}->clean to false to tell the
     * phpDocumentor_IntermediateParser that a page-level DocBlock can't be
     * found after this point on this page.  It then sets the package
     * to be the same as the page, and adds itself to the
     * {@link ProceduralPages} class
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserGlobal $data
     */
    
function handleGlobal($event,$data)
    {
        if (
$this->_lastDocBlockWasPageLevel)
        {
            
addWarning(PDERROR_DOCBLOCK_CONFLICT'global variable'$data->getName());
            if (!
$this->_oldPageLevel)
            {
                unset(
$this->last);
            }
        }
        
$this->_lastDocBlockWasPageLevel false;
        
$this->data->clean false;
        if (
$this->private_page)
        {
            unset(
$this->last);
            return;
        }
        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
if ($this->last->getKeyword('ignore'))
        {
            
addWarning(PDERROR_IGNORE_TAG_IGNORED,'global variable - just don\'t document the',$data->getName());
            
$this->last false;
            return;
        }
        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'global');
        
$data->setDocBlock($this->last);
        if (
$data->docblock->getKeyword('name'))
        {
            
$a $data->docblock->getKeyword('name');
            if (
is_object($a)) $a $a->value;
            
$data->setName($a);
        }
        
$this->proceduralpages->addGlobal($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of Package-level documentation pages.
     *
     * sets the {@link $package_pages}[$data->package] to $data
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserPackagePage $data
     */
    
function handlePackagePage($event,$data)
    {
        
$this->package_pages[$data->package] = &$data;
        
$this->last false;
    }

    
/**
     * handle post-parsing of Tutorials.
     *
     * This adds the parsed tutorial to the tutorial tree
     * @uses $tutorials sets the value of tutorials to parameter $data
     * @param integer $event Event Number
     * @param parserTutorial $data
     * @since 1.2
     */
    
function handleTutorial($event,$data)
    {
        if (isset(
$this->packagecategories[$data->package]))
        {
            
$data->category $this->packagecategories[$data->package];
        } else
        {
            
$data->category $GLOBALS['phpDocumentor_DefaultCategoryName'];
        }
        
$this->tutorials[$data->package][$data->subpackage][$data->tutorial_type][$data->name] = $data;
    }

    
/**
     * handles post-parsing of class vars
     *
     * This function sets up a @var tag if none is found, and aligns $data's
     * $path var and packages to match the parent object
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserVar $data
     */
    
function handleVar($event,$data)
    {
        global 
$_phpDocumentor_setting;
        if (
$this->private_class)
        {
            unset(
$this->last);
            return;
        }
        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'var');
        
$this->last->updateModifiers($data->getModifiers());

        if (
$this->last->getKeyword('ignore'))
        {
            
$this->last false;
            return;
//            addWarning(PDERROR_IGNORE_TAG_IGNORED,'var',$this->cur_class.'::'.$data->getName());
        
}
        if (!
$this->last->var)
        {
            
$this->last->addVar('mixed',new parserStringWithInlineTags);
        }

        if (isset(
$_phpDocumentor_setting['pear']) && $_phpDocumentor_setting['pear'])
        {
            if (
strpos($data->getName(), '_') == && !$this->last->getKeyword('access'))
            {
                
addWarning(PDERROR_PRIVATE_ASSUMED,'class variable',$data->class.'::'.$data->getName());
                
$this->last->addKeyword('access','private');
                
$data->setDocBlock($this->last);
            }
        }
        
$data->setDocBlock($this->last);
        
$data->path $this->data->parent->path;
        
$this->classes->addVar($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of class constants
     *
     * This function aligns $data's
     * $path var and packages to match the parent object
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserVar $data
     */
    
function handleConst($event,$data)
    {
        global 
$_phpDocumentor_setting;
        if (
$this->private_class)
        {
            unset(
$this->last);
            return;
        }
        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'const');

        if (
$this->last->getKeyword('ignore'))
        {
            
$this->last false;
            return;
//            addWarning(PDERROR_IGNORE_TAG_IGNORED,'var',$this->cur_class.'::'.$data->getName());
        
}
        
$data->setDocBlock($this->last);
        
$data->path $this->data->parent->path;
        
$this->classes->addConst($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of class methods
     *
     * This function first aligns $data's path and package to match the parent
     * object, and also aligns the docblock's @param, @global, and @staticvar
     * tags with the information parsed from the method source code.  It also
     * checks to see if the method is a constructor and sets the $isConstructor
     * flag.  If source code has been parsed by a {@}source} tag, the source is
     * added to its docblock
     *
     * Finally, it adds the method to the {@link Classes} class.
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserMethod $data
     */
    
function handleMethod($event,$data)
    {
        global 
$_phpDocumentor_setting;
        if (
$this->private_class)
        {
            unset(
$this->last);
            return;
        }

        if (empty(
$this->last))
        {
            if (
$this->undocumentedElementWarnings)
            {
                
addWarning(PDERROR_UNDOCUMENTED_ELEMENT,'Method',$data->getName(),'method');
            }
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
if ($this->last->getKeyword('ignore'))
        {
            
$this->last false;
            return;
//            addWarning(PDERROR_IGNORE_TAG_IGNORED,'method',$this->cur_class.'::'.$data->getName());
        
}
        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'method');
        if (
$data->hasSource())
        {
            
$this->last->setSource($data->getSource(), $data->getClass());
        }
        foreach(
$data->listParams() as $key => $param)
        {
            
$update_params[$key] = $param;
        }
        foreach(
$data->listGlobals() as $param)
        {
            
$update_globals[] = $param[1];
        }
        foreach(
$data->listStatics() as $param)
        {
            
$update_statics[] = $param[0];
        }
        if (isset(
$update_params))
        
$this->last->updateParams($update_params);
        if (isset(
$update_globals))
        
$this->last->updateGlobals($update_globals);
        if (isset(
$update_statics))
        
$this->last->updateStatics($update_statics);
        
$this->last->updateModifiers($data->getModifiers());
        unset(
$update_params);
        unset(
$update_globals);
        unset(
$update_statics);

        if (
$data->getName() == $this->cur_class$data->setConstructor();
        if (
$data->getName() == '__construct') {
            
$data->setConstructor();
        }
        if (
$data->getName() == '__destruct') {
            
$data->setDestructor();
        }

        if (isset(
$_phpDocumentor_setting['pear']) && $_phpDocumentor_setting['pear'])
        {
            if (
strpos($data->getName(), '_') === && substr($data->getName(), 1) == $data->class)
            { 
// is destructor
                
$data->setDestructor();
            } elseif (
strpos($data->getName(), '_') === && !$this->last->getKeyword('access'))
            {
                if (
strpos($data->getName(), '__') !== 0) {
                    
addWarning(PDERROR_PRIVATE_ASSUMED,'method',$data->class.'::'.$data->getName().'()');
                    
$this->last->addKeyword('access','private');
                    
$data->setDocBlock($this->last);
                }
            }
        }
        
$data->setDocBlock($this->last);
        
$data->path $this->data->parent->path;
        
$this->classes->addMethod($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of functions
     *
     * This function sets {@link $data}->clean to false to tell the
     * phpDocumentor_IntermediateParser that a page-level DocBlock can't be
     * found after this point on this page.  It then sets the package to be the
     * same as the page, aligns the docblock's @param, @global, and @staticvar
     * tags with the information parsed from the function source code.
     *
     * If source code has been parsed by a {@}source} tag, the source is added
     * to its docblock, and then the parserFunction adds itself to the
     * {@link ProceduralPages} class
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserFunction $data
     */
    
function handleFunction($event,$data)
    {
        if (
$this->_lastDocBlockWasPageLevel)
        {
            
addWarning(PDERROR_DOCBLOCK_CONFLICT'function'$data->getName());
            if (!
$this->_oldPageLevel)
            {
                unset(
$this->last);
            }
        }
        
$this->_lastDocBlockWasPageLevel false;
        
$this->data->clean false;
        if (
$this->private_page)
        {
            unset(
$this->last);
            return;
        }

        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
if ($this->last->getKeyword('ignore'))
        {
            unset(
$this->last);
            return;
        }
        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'function');

        foreach(
$data->listParams() as $key => $param)
        {
            
$update_params[$key] = $param;
        }
        foreach(
$data->listGlobals() as $param)
        {
            
$update_globals[] = $param[1];
        }
        foreach(
$data->listStatics() as $param)
        {
            
$update_statics[] = $param[0];
        }
        if (isset(
$update_params))
        
$this->last->updateParams($update_params);
        if (isset(
$update_globals))
        
$this->last->updateGlobals($update_globals);
        if (isset(
$update_statics))
        
$this->last->updateStatics($update_statics);
        unset(
$update_params);
        unset(
$update_globals);
        unset(
$update_statics);

        if (
$data->hasSource())
        {
            
$this->last->setSource($data->getSource());
        }
        if (
count($this->last->params) == && !count($data->listParams()))
        {
            
// if the function has no parameters, and 1 @param, add it to the list as optional, default value is description from @param
            
$pars $this->last->listParams();
            
$data->addParam($pars[0]['var'],$pars[0]['data']->getString());
        }
        
$data->setDocBlock($this->last);
        
$this->proceduralpages->addFunction($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of defines
     *
     * This function sets {@link $data}->clean to false to tell the
     * phpDocumentor_IntermediateParser that a page-level DocBlock can't be
     * found after this point on this page.  It then sets the package to be the
     * same as the page and adds itself to the {@link ProceduralPages} class
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserDefine $data
     */
    
function handleDefine($event,$data)
    {
        if (
$this->_lastDocBlockWasPageLevel)
        {
            
addWarning(PDERROR_DOCBLOCK_CONFLICT'define'$data->getName());
            if (!
$this->_oldPageLevel)
            {
                unset(
$this->last);
            }
        }
        
$this->_lastDocBlockWasPageLevel false;
        
$this->data->clean false;
        if (
$this->private_page)
        {
            unset(
$this->last);
            return;
        }
        if (empty(
$this->last))
        {
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
        }
//        $this->last->setLineNumber($data->getLineNumber());
        
if ($this->last->getKeyword('ignore'))
        {
            unset(
$this->last);
            return;
        }

        
$this->last->overridePackage($this->category,$this->package,$this->subpackage,$data->getName(),'define');
        
$data->setDocBlock($this->last);
        
$this->proceduralpages->addDefine($data);
        
$this->last false;
    }

    
/**
     * handles post-parsing of classes
     *
     * This function sets {@link $data}->clean to false to tell the
     * phpDocumentor_IntermediateParser that a page-level DocBlock can't be
     * found after this point on this page.  It sets {@link $cur_class} to its
     * name, and if an @ignore tag is found in the DocBlock, it sets
     * {@link $private_class} to true, to prevent post-parsing of any of the
     * class's vars or methods.  Then it checks for the existence of a package
     * page for the class's package
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserClass $data
     */
    
function handleClass($event,$data)
    {
        global 
$_phpDocumentor_setting;
        if (
$data->isInterface())
        {
            
$objectType 'interface';
        }
        else
        {
            
$objectType 'class';
        }
        if (
$this->_lastDocBlockWasPageLevel)
        {
            if (!
$this->_oldPageLevel)
            {
                
addWarning(PDERROR_DOCBLOCK_GOES_CLASS$data->getName());
                
$doc = new parserDocBlock;
                
$doc->category $this->category;
                
$doc->package $this->package;
                
$doc->subpackage $this->subpackage;
                if (isset(
$_phpDocumentor_setting['sourcecode']) &&
                    
$_phpDocumentor_setting['sourcecode']) {
                    
$doc->canSource();
                    
$doc->addFileSource($this->data->parent->path$this->data->parent->source);
                }
                
$this->data->setDocBlock($doc);
                unset(
$doc);
                if (
$this->last) {
                    
$this->last->cantSource();
                }
            }
        }
        
$this->_lastDocBlockWasPageLevel false;
        
$this->data->clean false;
        if (empty(
$this->last))
        {
            if (
$this->undocumentedElementWarnings)
            {
                
addWarning(PDERROR_UNDOCUMENTED_ELEMENT,'Class',$data->getName(),'Class');
            }
            if (isset(
$this->db_template))
            {
                
// use the docblock template
                
$this->last phpDocumentor_clone($this->db_template);
            }
            else
            {
                
// we don't have a docblock, create an empty one to get rid of errors
                
$this->last = new parserDocblock();
            }
            list(
$this->last->package$this->last->subpackage) = $this->_guessPackage($this->data->parent->path$this->data->parent->getSourceLocation('dummy'));
            
addWarning(PDERROR_NO_PACKAGE_TAG,$objectType,$data->getName(),$this->last->package);
        } else
        {
            if (!
$this->last->getExplicitPackage())
            {
                list(
$this->last->package$this->last->subpackage) = $this->_guessPackage($this->data->parent->path$this->data->parent->getSourceLocation('dummy'));
                
addWarning(PDERROR_NO_PACKAGE_TAG,$objectType,$data->getName(),$this->last->package);
            } else
            {
                if (isset(
$this->packagecategories[$this->package])
                    && 
$this->packagecategories[$this->package] != $this->category)
                    
addWarning(PDERROR_PACKAGECAT_SET,$this->package,
                                
$this->packagecategories[$this->package],
                                
$this->category);
                
$this->packagecategories[$this->package] = $this->category;
            }
        }
        
$this->last->updateModifiers($data->getModifiers());
//        $this->last->setLineNumber($data->getLineNumber());
        
$data->setDocBlock($this->last);
        
$this->cur_class $name $data->getName();
        if (
$this->last->getKeyword('ignore'))
        {
            
$this->private_class true;
            unset(
$this->last);
            return;
        }
        
$data->path $this->data->parent->path;
        
$this->classes->addClass($data);
        
$this->private_class false;
        if (
$this->last->package)
        {
            
$this->parsePackagePage($this->last->package$this->data->parent->getPath());
        }
        
$this->last false;
    }

    
/**
     * handles post-parsing of procedural pages
     *
     * this event is called at the start of a new page, before the Parser knows
     * whether the page will contain any procedural pages or not
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserPage $data
     */
    
function handlePage($event,$data)
    {
        
$type 'page';
        
$this->private_page false;
        
$this->data = new parserData;
        
$data->category $this->category $GLOBALS['phpDocumentor_DefaultCategoryName'];
        
$this->package $GLOBALS['phpDocumentor_DefaultPackageName'];
        
$this->subpackage '';
        
$this->proceduralpages->addPage($data);
        
$this->data->setParent($data);
        
$this->pages[$data->getPath()] = $this->data;
        
$this->classes->nextFile($data->getPath());
        
$this->packageoutput $data->getPackageOutput();
    }

    
/**
     * handles post-parsing of DocBlocks
     *
     * This function sets {@link $last} to the DocBlock represented by $data, to
     * allow the next documentable element passed to
     * phpDocumentor_IntermediateParser to link the DocBlock into its $docblock
     * property.  This function also checks for two special cases of DocBlocks:
     * <ol>
     *    <li>First DocBlock in the file contains a @package tag</li>
     *    <li>First DocBlock in the file is immediately followed by another
     *        DocBlock</li>
     * </ol>
     * In both cases, the function extracts this tag and uses it as the
     * page-level package.  If the @package tag is in the DocBlock of an
     * element (function, global variable, whatever) that isn't a page-level
     * DocBlock, a warning will be raised to notify the author that a @package
     * tag belongs in a page-level DocBlock.
     *
     * <b>New</b> in version 1.2.2, if the first DocBlock in a file contains
     * a @package tag, it is a page-level DocBlock.
     *
     * If the DocBlock is page-level, it is processed with
     * {@link _processPageLevelDocBlock}
     *
     * Finally, the function replaces the old parserPage in
     * {@link parserData::$data}->parent with the new one containing information
     * from the DocBlock by calling {@link addPage()}, and checks for
     * package-level docs.
     * @param integer $event Event number from {@link Parser.inc}
     * @param parserDocBlock $data
     */
    
function handleDocBlock($event,$data)
    {
        
$type 'docblock';
        
$data->postProcess();
        
// Zend desc support
        
if ($tdesc $data->getKeyword('desc'))
        {
            
$data->setShortDesc($tdesc);
            unset(
$data->tags['desc']);
        }
        
$this->_lastDocBlockWasPageLevel false;
        
// 1st docblock in file, check for @package
        
if ($this->data->isClean() && !isset($this->last))
        {
            if (
$data->getExplicitPackage())
            {
                
// new with 1.2.2:
                // if the first docblock in a file
                // contains a @package tag, then it is
                // a page-level docblock
                
$this->_processPageLevelDocBlock($data);
                
$this->_lastDocBlockWasPageLevel true;
                
$this->all_packages[$data->package] = 1;
                
$this->last $data;
                return;
            }
            
$doc = new parserDocBlock;
            
$doc->category $this->category;
            
$doc->package $this->package;
            
$doc->subpackage $this->subpackage;
            
$this->data->setDocBlock($doc);
            
$this->proceduralpages->addPagePackage($this->data->parent->getPath(),$this->package,$this->subpackage);
            unset(
$doc);
        }
        
// 2nd docblock in a row, and it's at the top of the file, page-level docblock
        
if ($this->lasttype == "docblock" && $this->data->isClean())
        {
            
$this->_processPageLevelDocBlock($this->last);
            
$this->_oldPageLevel true;
            
$this->_lastDocBlockWasPageLevel false;
        }
        
$this->all_packages[$data->package] = 1;
        
$this->last $data;
    }

    
/**
     * Process a Page-level DocBlock
     *
     * First, it checks for an @ignore tag,
     * and if found, calls {@link ProceduralPages::ignorePage()}.  An @ignore
     * tag in a page-level DocBlock will ignore all functions, defines, global
     * variables, and includes.  It will not ignore classes!  The function next
     * checks for an @access private, and if --parseprivate is off, performs the
     * same actions as @ignore.
     * Next, it checks for the @name tag, which is used to rename the page.
     * This is also a PEAR compatibility issue, and may not be very useful in
     * the long run.  Documentation is best when it refers to real entities in
     * the package, and not to aliases.
     * @access private
     */
    
function _processPageLevelDocBlock($data)
    {
        global 
$_phpDocumentor_setting;
        
// can only have 1 package-level docblock, others are ignored
        
if (!$this->data->isClean())
        {
            return;
        }
        
$this->data->clean false;
        
$this->data->explicitDocBlock();
        
$data->canSource();
        if (isset(
$_phpDocumentor_setting['source']) && $_phpDocumentor_setting['sourcecode'])
        {
            
$data->addFileSource($this->data->parent->path$this->data->parent->source);
        }
        if (!
$data->getExplicitPackage())
        {
            list(
$data->package,$data->subpackage) = $this->_guessPackage($this->data->parent->getPath(), $this->data->parent->getSourceLocation('dummy'));
            
addWarning(PDERROR_NO_PACKAGE_TAG,'file',$this->data->parent->getPath(),$this->last->package);
        }
        if (isset(
$this->packagecategories[$this->package])
            && 
$this->packagecategories[$this->package] != $data->category)
            
addWarning(PDERROR_PACKAGECAT_SET,$this->package,
                        
$this->packagecategories[$this->package],
                        
$data->category);
        
$this->packagecategories[$this->package] = $data->category;
        
$this->category $this->data->parent->category $data->category;
        
$this->packagecategories[$this->package] = $this->category;
        
$this->subpackage $this->data->parent->subpackage $data->subpackage;
        
$this->data->setDocBlock($data);
        if (
$data->getKeyword('ignore'))
        {
            
$this->proceduralpages->ignorePage($this->data->parent);
            
$this->private_page true;
            unset(
$this->last);
            
$this->privatepages[$this->data->parent->getPath()] = $this->data;
            unset(
$this->pages[$this->data->parent->getPath()]);
            return;
        }
        
$this->package $this->data->parent->package $data->package;
        
$this->subpackage $this->data->parent->subpackage $data->subpackage;
        
$this->proceduralpages->addPagePackage($this->data->parent->getPath(),$this->package,$this->subpackage);
        if (
$access $data->getKeyword('access'))
        {
            if (
is_object($access) && ($access->getString() == 'private') && (!$this->parsePrivate))
            {
                
$this->proceduralpages->ignorePage($this->data->parent);
                
$this->private_page true;
                unset(
$this->last);
                
$this->privatepages[$this->data->parent->getPath()] = $this->data;
                unset(
$this->pages[$this->data->parent->getPath()]);
                return;
            }
        }
        if (
$data->getKeyword('name'))
        {
            
$a $data->getKeyword('name');
            if (
is_object($a)) $a $a->value;
            
$this->data->parent->setFile($a);
            
$this->proceduralpages->setName($a);
        }
        
$this->addPage($this->data->parent$this->data->parent->getPath());
        if (
$this->package)
        {
            
$this->parsePackagePage($this->package$this->data->parent->getPath());
        }
    }

    
/**
     * Backward-compatibility only, use the new tutorials for more power
     * @tutorial tutorials.pkg
     * @param string package name of package file to parse
     * @param string directory of file that contains package name
     */
    
function parsePackagePage($package$path)
    {
        if (!isset(
$this->package_pages[$package]))
        {
            if (
file_exists(dirname($path) . SMART_PATH_DELIMITER $package '.html'))
            {
                if (
$this->quietMode === false)
                {
                    
phpDocumentor_out("Reading package-level file ".$package '.html');
                          
flush();
                }
                
$fp fopen(dirname($path) . SMART_PATH_DELIMITER $package '.html',"r");
                
$ret fread($fp,filesize(dirname($path) . SMART_PATH_DELIMITER $package '.html'));
                
fclose($fp);
                unset(
$fp);
                if (
$this->quietMode === false)
                {
                    
phpDocumentor_out(" -- Parsing File\n");
                          
flush();
                }
                
$pageParser = new ppageParser;
                
$tempp $this->package;
                
$lp $this->last;
                
$pageParser->subscribe('*',$this);
                
$pageParser->parse($ret,false,$package);
                
$this->package $tempp;
                
$this->last $lp;
                unset(
$tempp);
                unset(
$pageParser);
            }
        }
    }

    
/**
     * called via {@link Parser::parse()} and Parser's inherited method
     * {@link Publisher::publishEvent()}
     *
     * $event is one of the PHPDOC constants from Parser.inc.  If it is not
     * PHPDOCUMENTOR_EVENT_NEWSTATE, then a function name is retrieved from the
     * {@link $event_handlers} array and called to handle the $data
     * @param integer $event event number from {@link Parser.inc}
     * @param mixed $data if $event is {@link PHPDOCUMENTOR_EVENT_NEWSTATE}, $data is a {@link PHP_DOC_EVENT_END_PAGE} or {@link STATE_END_CLASS},
     *                    otherwise $data is either a {@link parserDocBlock}, {@link parserPage} or descendant of {@link parserElement}
     * @global array we use 'sourcecode' to determine whether to highlight the source
     *               of the current file if it has no file-level docblock
     */
    
function HandleEvent($event,$data)
    {
        global 
$_phpDocumentor_setting;
        global 
$phpDocumentor_DefaultPackageName$phpDocumentor_DefaultCategoryName;
        if (empty(
$this->packagecategories))
        
$this->packagecategories[$phpDocumentor_DefaultPackageName] = $phpDocumentor_DefaultCategoryName;
        if (
$event == PHPDOCUMENTOR_EVENT_NEWSTATE)
        {
            if (
$data == STATE_END_CLASS)
            {
            } elseif (
$data == PHPDOCUMENTOR_EVENT_END_PAGE)
            {
                if (!
$this->private_page)
                {
                    
$this->all_packages[$this->package] = 1;
                    if (!
$this->data->hasExplicitDocBlock())
                    {
                        
$doc $this->data->docblock;
                        if (!
$this->data->docblock)
                        {
                            
$doc = new parserDocBlock;
                        }
                        if (isset(
$_phpDocumentor_setting['sourcecode']) &&
                            
$_phpDocumentor_setting['sourcecode'])
                        {
                            
$doc->canSource();
                            
$doc->addFileSource($this->data->parent->path$this->data->parent->source);
                        }
                        list(
$doc->package,$doc->subpackage) = $this->_guessPackage($this->data->parent->getPath(), $this->data->parent->getSourceLocation('dummy'));
                        
addWarning(PDERROR_NO_PAGE_LEVELDOCBLOCK,$this->data->parent->getPath());
                        
$this->data->setDocBlock($doc);
                        
$this->proceduralpages->addPage($this->data->parent,$doc->package,$doc->subpackage);
                    }
                    
$this->pages[$this->data->parent->getPath()] = $this->data;
                }
                
$this->private_page false;
                
$this->private_class false;
                if (isset(
$this->db_template))
                {
                    
addWarning(PDERROR_DB_TEMPLATE_UNTERMINATED);
                }
                unset(
$this->db_template);
                unset(
$this->last);
            } elseif (
$data == PHPDOCUMENTOR_EVENT_END_DOCBLOCK_TEMPLATE)
            {
                unset(
$this->db_template);
            }
            
//echo $this->state_lookup[$data] . "\n";
            //echo $data."\n";
        
}
         else
        {
            if (
$event == PHPDOCUMENTOR_EVENT_README_INSTALL_CHANGELOG)
            {
                
$this->ric[$data[0]] = $data[1];
                return;
            }
            if (
$event == PHPDOCUMENTOR_EVENT_DOCBLOCK_TEMPLATE)
            {
                
$data->postProcess();
                
$this->db_template $data;
                
$this->_lastDocBlockWasPageLevel false;
                
// 2nd docblock in a row, and it's at the top of the file, page-level docblock
                
if ($this->type == "docblock" && $this->data->isClean())
                {
                    
// can only have 1 package-level docblock, others are ignored
                    
$this->data->clean false;
                    if (
$this->last->getKeyword('ignore'))
                    {
                        
$this->proceduralpages->ignorePage($this->data->parent);
                        
$this->private_page true;
                        unset(
$this->last);
                        
$this->privatepages[$this->data->parent->getPath()] = $this->data;
                        unset(
$this->pages[$this->data->parent->getPath()]);
                        return;
                    }
                    
$this->data->setDocBlock($this->last);
                    
$this->package $this->data->parent->package $this->last->package;
                    
$this->subpackage $this->data->parent->subpackage $this->last->subpackage;
                    
$this->proceduralpages->addPagePackage($this->data->parent->getPath(),$this->package,$this->subpackage);
                    if (
$access $this->last->getKeyword('access'))
                    {
                        if (
is_object($access) && ($access->getString() == 'private') && (!$this->parsePrivate))
                        {
                            
addWarning(PDERROR_PARSEPRIVATE$this->data->parent->getPath());
                            
$this->proceduralpages->ignorePage($this->data->parent);
                            
$this->private_page true;
                            unset(
$this->last);
                            
$this->privatepages[$this->data->parent->getPath()] = $this->data;
                            unset(
$this->pages[$this->data->parent->getPath()]);
                            return;
                        }
                    }
                    if (
$this->last->getKeyword('name'))
                    {
                        
$a $this->last->getKeyword('name');
                        if (
is_object($a)) $a $a->value;
                        
$this->data->parent->setFile($a);
                        
$this->proceduralpages->setName($a);
                    }
                    
$this->addPage($this->data->parent$this->data->parent->getPath());
                    if (
$this->package)
                    {
                        
$this->parsePackagePage($this->package$this->data->parent->getPath());
                    }
                }
                unset(
$this->last);
            } else
            {
                
$this->lasttype $this->type;
                
$type $data->getType();
//                fancy_debug($type,$data);
                
if (($type != 'page') && ($type != 'docblock') && ($type != 'packagepage') && ($type != 'tutorial'))
                {
                    
$data->setFile($this->data->parent->getFile());
                }
                
$this->type $type;
                
//echo $type . "\n";

                
if (isset($this->event_handlers[$type]))
                {
                    
$handle $this->event_handlers[$type];
                    
$this->$handle($event,$data);
                }
            }
        }
    }

    
/**
     * Replaces the {@link parserPage} represented by $this->pages[$path] with
     * $page
     *
     * Called by {@link addPageIfNecessary(), handleDocBlock()} and
     * {@link ProceduralPages::setupPages()}, this method first checks to see if
     * the page has been added.  If not, it assumes that the page has either
     * been @ignored or set with @access private with --parseprivate off, and
     * returns {@link addPrivatePage()}.  Otherwise, it sets the pages[$path] to
     * be the parserPage $page and sets the package and subpackage to that of
     * $page
     * @see $pages
     * @param parserPage
     * @param string full path to the file
     */
    
function addPage($page$path)
    {
        if (!isset(
$this->pages[$path])) return $this->addPrivatePage($page$path);
        
$this->pages[$path]->setParent($page);
        if (
$page->package != $GLOBALS['phpDocumentor_DefaultPackageName'])
        {
            if (!
$this->pages[$path]->docblock)
            {
                
$docblock = new parserDocBlock;
                
$docblock->package $page->package;
                
$docblock->subpackage $page->subpackage;
                
$this->pages[$path]->docblock $docblock;
            } else
            {
                
$this->pages[$path]->docblock->package $page->package;
                
$this->pages[$path]->docblock->subpackage $page->subpackage;
            }
        }
    }

    
/**
     * add a new {@link parserPage} to the $pages array if none is found
     *
     * This method is used when a page has been @ignored or marked with @access
     * private, and a public class is in the page (a class with no @access
     * private in its DocBlock).  The method first creates a new page in the
     * {@link $pages} array and then copies path information, and calls
     * {@link addPage()} to set up packages
     * @param string full path of page
     */
    
function addPageIfNecessary($path, &$class)
    {
        global 
$_phpDocumentor_setting;
        if (!
$this->parsePrivate)
        {
            if (!isset(
$this->pages[$path]))
            {
                
$this->pages[$path] = new parserData;
                
$this->pages[$path]->docblock = new parserDocBlock;
                
$this->pages[$path]->docblock->package $this->privatepages[$path]->docblock->package;
                
$this->pages[$path]->docblock->subpackage $this->privatepages[$path]->docblock->subpackage;
                
$par $this->privatepages[$path]->parent;
                
$this->pages[$path]->setParent($par);
                
$this->proceduralpages->addPage($par);
            }
        }
        if (!empty(
$_phpDocumentor_setting['packageoutput']))
            
$packages explode(',',$_phpDocumentor_setting['packageoutput']);
        if (!empty(
$_phpDocumentor_setting['packageoutput']) &&
            
$this->pages[$path]->parent->package != $class->docblock->package &&
            !
in_array($this->pages[$path]->parent->package,$packages))
        {
            
$this->pages[$path]->parent->package $class->docblock->package;
            
$this->addPage($this->pages[$path]->parent$path);
            
$this->proceduralpages->addPage($this->pages[$path]->parent);
        }
    }

    
/**
     * Adds a {@link parserPage} element to the {@link parserData} element in
     * $this->privatepages[$path]
     *
     * Performs a similar function to addPage, but adds to the
     * {@link $privatePages} array
     * @param parserPage $page
     * @param string $path full path to the page
     * @see addPage()
     */
    
function addPrivatePage($page$path)
    {
        
/*
         * if privatepages is still empty,
         * we need to initialize it with an empty
         * path=>ParserData element, so that it has
         * a top-level element... otherwise the setParent() call
         * below will crap out.
         */
        
if (count($this->privatepages) == 0) {
            
$this->privatepages[$path] = new ParserData();
        }
        
$this->privatepages[$path]->setParent($page);
        if (isset(
$page->package) && $page->package != $GLOBALS['phpDocumentor_DefaultPackageName'])
        {
            if (!
$this->privatepages[$path]->docblock)
            {
                
$docblock = new parserDocBlock;
                
$docblock->package $page->package;
                
$docblock->subpackage $page->subpackage;
                
$this->privatepages[$path]->docblock $docblock;
            } else
            {
                
$this->privatepages[$path]->docblock->package $page->package;
                
$this->privatepages[$path]->docblock->subpackage $page->subpackage;
            }
        }
    }

    
/**
     * adds a processed descendant of {@link parserElement} to the {@link $pages}
     * array or {@link $privatepages} array
     *
     * This function expects the page to exist in either $pages or $privatepages.  It calls the
     * {@link parserData::addElement()} method to add $element to the page.
     * @param parserElement $element this will actually be a descendant of parserElement
     * @param string $path
     */
    
function addElementToPage($element$path)
    {
        if (isset(
$this->privatepages[$path]))
        {
            if (isset(
$this->pages[$path]))
            {
                if (
$element->type == 'class' || $element->type == 'method'
                    
|| $element->type == 'var' || $element->type == 'const')
                {
                    
$this->pages[$path]->addElement($element);
                } else
                
$this->privatepages[$path]->addElement($element);
            } else
            
$this->privatepages[$path]->addElement($element);
        } else
        {
            if (isset(
$this->pages[$path]))
            {
                
$this->pages[$path]->addElement($element);
            }
        }
    }

    
/**
     * Add all the @uses tags from $element to the $uses array so that @usedby
     * virtual tags can be added
     * @uses parserUsesTag::getSeeElement() used to initialize {@link $uses}
     * @uses parserUsesTag::getDescription() used to initialize {@link $uses}
     * @param parserElement descendant of parserElement
     * @param string full path to the file
     */
    
function addUses($element$path)
    {
        if (isset(
$element->type) && $element->type == 'page')
        {
            
$element $this->pages[$element->path];
        }
        if (!
$this->parsePrivate && isset($element->docblock->hasaccess) && $element->docblock->hasaccess)
        {
            
$a =  $element->docblock->getKeyword('access');
            if (
is_object($a) && $a->getString() == 'private') return;
        }
        if (isset(
$this->privatepages[$path]))
        {
            if (isset(
$this->pages[$path]))
            {
                
$uses $element->docblock->getKeyword('uses');
                if (
$uses)
                {
                    if (!
is_array($uses)) $uses = array($uses);
                    foreach(
$uses as $use)
                    {
                        if (!
is_object($use)) continue;
                        
$el $use->getSeeElement();
                        
$description $use->getDescription();
                        
$this->uses[$el][] = array($element$description);
                    }
                }
            }
        } else
        {
            if (isset(
$this->pages[$path]))
            {
                
$uses $element->docblock->getKeyword('uses');
                if (
$uses)
                {
                    if (!
is_array($uses)) $uses = array($uses);
                    foreach(
$uses as $use)
                    {
                        if (!
is_object($use)) continue;
                        
$el $use->getSeeElement();
                        
$description $use->getDescription();
                        
$this->uses[$el][] = array($element$description);
                    }
                }
            }
        }
    }

    
/**
     * Add a {@link parserUsedByTag} link to every element referred to by @uses
     * @param Converter temporary converter used to retrieve abstract links
     * @uses phpDocumentor_IntermediateParser::addUses() indirectly, as
     *       addUses() sets up $uses, which is iterated over here
     * @uses $pages sets up all @usedby tags from here
     * @access private
     */
    
function _setupUsesList(&$converter)
    {
        
ob_start();
        
$converter->_createPkgElements($this->pages);
        
ob_end_clean();
        
ksort($this->uses);
        foreach(
$this->uses as $link => $elements)
        {
            foreach(
$elements as $element)
            {
                if (
$element[0]->type == 'method' || $element[0]->type == 'var' ||
                    
$element[0]->type == 'const')
                {
                    
$converter->class $element[0]->getClass();
                }
                if (
$element[0]->type == 'class')
                {
                    
$converter->class $element[0]->getName();
                }
                
$reallink $converter->getLink($link,$element[0]->docblock->package);
                if (
is_object($reallink))
                {
                    
// add a used by tag to the docblock of the destination
                    
switch(phpDocumentor_get_class($reallink))
                    {
                        case 
'pagelink' :
                            
$this->pages[$reallink->path]->docblock->addUsedBy(
                                
$element[0]->getLink($converterfalsetrue),
                                
$element[1]);
                        break;
                        case 
'functionlink' :
                        case 
'definelink' :
                        case 
'globallink' :
                        if (isset(
$this->pages[$reallink->path]))
                        {
                            for (
$i=0;
                                 
$i<count($this->pages[$reallink->path]->elements);
                                 
$i++) {
                                if (
$this->pages[$reallink->path]->elements[$i]->type ==
                                      
str_replace('link''',
                                      
phpDocumentor_get_class($reallink)) &&
                                      
$this->pages[$reallink->path]->
                                      
elements[$i]->getName()
                                      == 
$reallink->name) {
                                    
$this->pages[$reallink->path]->elements[$i]->
                                    
docblock->addUsedBy(
                                        
$element[0]->getLink($converter,false,true),
                                        
$element[1]);
//                                   debug('added @usedby to '.str_replace('link','',phpDocumentor_get_class($reallink)).' '.$reallink->name);
                                
}
                            }
                        }
                        break;
                        case 
'classlink' :
                        case 
'methodlink' :
                        case 
'varlink' :
                        case 
'constlink' :
                        if (isset(
$this->pages[$reallink->path]))
                        {
                            for (
$i=0;$i<count($this->pages[$reallink->path]->classelements);$i++)
                            {
                                if (
$this->pages[$reallink->path]->classelements[$i]->type ==
                                      
str_replace('link','',phpDocumentor_get_class($reallink)) &&
                                      
$this->pages[$reallink->path]->classelements[$i]->getName() == $reallink->name &&
                                      (!isset(
$reallink->class) ||
                                      
$this->pages[$reallink->path]->classelements[$i]->getClass() == $reallink->class))
                                {
                                    
$this->pages[$reallink->path]->classelements[$i]->docblock->addUsedBy($element[0]->getLink($converter,false,true), $element[1]);
//                                   debug('added @usedby to '.str_replace('link','',phpDocumentor_get_class($reallink)).' '.$reallink->name);
                                
}
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    
/**
     * Interface to the Converter
     *
     * This function simply passes {@link $pages} and {@link package_pages} to
     * the walk() method, and then calls the Output() method.  Note that
     * Output() is not required to do anything, and in fact doesn't in
     * HTMLframesConverter.
     * @uses Converter::walk() passes {@link $pages} and {@link $package_pages}
     * @uses Converter::Output()
     */
    
function Convert($title$converter)
    {
        
$converter->walk($this->pages$this->package_pages);
        
$converter->Output($title);
        
$converter->cleanup();
    }

    
/**
     * Clean up classes
     *
     * {@source}
     * @access private
     * @uses Classes::Inherit() passes $this
     */
    
function fixClasses()
    {
        
$this->classes->Inherit($this);
    }

    
/**
     * Clean up Procedural Pages
     * {@source}
     * @access private
     * @uses ProceduralPages::setupPages() passes $this
     */
    
function fixProcPages()
    {
        
$this->proceduralpages->setupPages($this);
    }

    
/**
     * If the parent class of $class is in a different package, adds it to the
     * {@link $package_parents} array
     * @param parserClass &$class
     */
    
function addPackageParent(&$class)
    {
        if (!
is_array($class->parent)) return;
        
$par $this->classes->getClass($class->parent[1], $class->parent[0]);
        if (
$class->docblock->package == $par->docblock->package) return;
        
$this->package_parents[$class->docblock->package] = $par->docblock->package;
        if (!isset(
$this->package_parents[$par->docblock->package]) || !$this->package_parents[$par->docblock->package]) $this->package_parents[$par->docblock->package] = false;
    }

    
/**
     * Add a converter name to use to the list of converters
     *
     * Sets up the {@link $converters} array.
     * {@internal
     * First, the Converter's file is included, and then, if successful,
     * the converter classname is tested for existance.  If all is good,
     * then the templates are added to the list of converters/templates to use}}
     * @param string $output output format (HTML, PDF, XML).  Must be all caps
     * @param string $name Converter name (frames, for example, is the name of
     *                     HTMLframesConverter)
     * @param string $template template to use, should be a relative path to the
     *                         templates dir (like DOM/default)
     */
    
function addConverter($output,$name,$template)
    {
        if (
$this->templateBase) {
            
$templateBase str_replace('\\','/'$this->templateBase) . '/Converters';
        } else {
            if (
'C:\dmz\php\pear' != '@'.'PEAR-DIR@') {
                
$templateBase 'PhpDocumentor/phpDocumentor/Converters';
            } else {
                
$templateBase str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) . '/phpDocumentor/Converters';
            }
        }
        if (
strpos($name,PATH_DELIMITER))
        {
            
// include the parent template
            
$parent explode(PATH_DELIMITER,$name);
            
$parent $parent[0];
            if (!
class_exists($output $parent 'Converter')) {
                
$filename $templateBase '/' $output '/' $parent '/' $output
                    
$parent 'Converter.inc';
                if (
Io::isIncludeable($filename))
                {
                    include_once(
$filename);
                }
            }
            if (!
class_exists($output $parent 'Converter'))
            {
                
addError(PDERROR_CONVERTER_NOT_FOUND,"parent Converter ".$output $parent "Converter of child Converter ".$output str_replace(PATH_DELIMITER,'',$name) . "Converter");
            }
        }
        
$filename $templateBase .
             
PATH_DELIMITER $output PATH_DELIMITER $name PATH_DELIMITER $output .
             
str_replace(PATH_DELIMITER''$name) . "Converter" ".inc";
        if (
Io::isIncludeable($filename))
        {
            include_once(
$filename);
        }
        if (
class_exists($output str_replace(PATH_DELIMITER,'',$name) . 'Converter'))
        {
            
$this->converters[$output][$output str_replace(PATH_DELIMITER,'',$name) . "Converter"][] = $template;
        } else
        {
            
addError(PDERROR_CONVERTER_NOT_FOUND,$output str_replace(PATH_DELIMITER,'',$name) . "Converter");
        }
    }

    
/**
     * does a natural case sort on two {@link parserElement} descendants
     *
     * @param    mixed    $a
     * @param    mixed    $b
     * @return    int
     * @see        generateElementIndex()
     */
    
function elementCmp ($a$b)
    {
        return 
strnatcasecmp($a->getName(), $b->getName());
    }

    
/**
     * does a natural case sort on two class elements (either
     * {@link parserClass, parserMethod} or {@link parserVar}
     *
     * @param    mixed    $a
     * @param    mixed    $b
     * @return    int
     * @see        generateElementIndex()
     */
    
function ClasselementCmp ($a$b)
    {
        if (
phpDocumentor_get_class($a) == 'parserclass'$atest $a->name; else $atest $a->class;
        if (
phpDocumentor_get_class($b) == 'parserclass'$btest $b->name; else $btest $b->class;

        if((
$c strnatcasecmp($atest$btest)) != 0) return $c;
        if (
phpDocumentor_get_class($a) != 'parserclass'$atest .= $a->name;
        if (
phpDocumentor_get_class($b) != 'parserclass'$btest .= $b->name;
        if (
phpDocumentor_get_class($a) == 'parsermethod' && phpDocumentor_get_class($b) == 'parsermethod')
        {
            if (
$a->isConstructor) return -1;
            if (
$b->isConstructor) return 1;
            if (
$a->isDestructor) return -1;
            if (
$b->isDestructor) return 1;
        }
        return 
strnatcasecmp($atest,$btest);
    }

    
/**
     * call this method once parsing has completed.
     *
     * This method calls the private methods fixClasses and fixProcPages, both
     * of which adjust inheritance and package information based on complicated
     * post-parsing rules described in {@link ProceduralPages::setupPages()}
     * and {@link Classes::Inherit()}.  Then, it sorts elements of the $pages
     * array and calls Convert for each Converter in the $converters array
     * @see $converters
     * @see $pages
     * @see Convert()
     */
    
function Output ($title "Generated Documentation")
    {
        
$GLOBALS['phpDocumentor_errors']->curfile false;
        
$this->fixClasses();
        
$this->fixProcPages();
//        var_dump($this->uses);
//        exit;
        
phpDocumentor_out("\nSorting page elements...");
        
flush();
        
uasort($this->pages,'pagesort');
        foreach(
$this->pages as $i => $page)
        {
            
usort($this->pages[$i]->elements,array($this,'elementCmp'));
            
usort($this->pages[$i]->classelements,array($this,'ClasselementCmp'));
        }
        
phpDocumentor_out("done\n");
        
flush();
        
$complicatedout false;
        if (
is_array($this->converters))
        {
            if (
count($this->converters) > 1)
            {
                
$complicatedout true;
            }
            
phpDocumentor_out("Formatting @uses list...");
            
flush();
            
$a = new __dummyConverter($this->all_packages$this->package_parents$this->classes$this->proceduralpages$this->packageoutput$this->parsePrivate$this->quietMode$this->targetDir ''$this->title);
            
$this->_setupUsesList($a);
            unset(
$a);
            
phpDocumentor_out("done\n\n");
            
flush();
            foreach(
$this->converters as $converter => $blah)
            {
                if (
is_array($blah))
                {
                    if (
count($blah) > 1)
                    {
                        
$complicatedout true;
                    }
                    foreach(
$blah as $converter => $templates)
                    {
                        foreach(
$templates as $template)
                        {
                            
$extraout '';
                            if (
$complicatedout)
                            {
                                
$extraout SMART_PATH_DELIMITER $converter;
                            }
                            if (
count($templates) > 1)
                            {
                                
$extraout .= SMART_PATH_DELIMITER str_replace(PATH_DELIMITERSMART_PATH_DELIMITERsubstr($template,0,strlen($template) - 1));
                            }
                            
$a = new $converter($this->all_packages$this->package_parents$this->classes$this->proceduralpages$this->packageoutput$this->parsePrivate$this->quietMode$this->targetDir $extraout$template$this->title);
                            if (isset(
$this->templateBase))
                            {
                                
$a->setTemplateBase($this->templateBase$template);
                            }
                            
$a->ric $this->ric;
                            
$a->packagecategories $this->packagecategories;
                            if (isset(
$this->tutorials)) $a->setTutorials($this->tutorials);
                            
$this->Convert($title$a);
                            unset(
$a);
                        }
                    }
                }
            }
        } else
        {
            
addErrorDie(PDERROR_NO_CONVERTERS);
        }
    }

    
/**
     * Sets the output directory
     *
     * @param string $dir the output directory
     */
    
function setTargetDir($dir)
    {
        
$this->targetDir $dir;
    }

    
/**
     * Sets the template base directory
     *
     * @param string $dir the template base directory
     * @tutorial phpDocumentor.howto.pkg#using.command-line.templatebase
     */
    
function setTemplateBase($dir)
    {
        
$this->templateBase $dir;
    }

    
/**
     * set parsing information output mode (quiet or verbose)
     *
     * If set to false, no parsing information (parsing /php/file/thisfile.php,
     * Converting etc.) will be displayed.
     * Useful for cron jobs
     * @param    bool $quietMode
     */
    
function setQuietMode($quietMode)
    {
        
$this->quietMode $quietMode;
    }

    
/**
     * show warnings for undocumented elements
     *
     * If set to false, no warnings will be shown for undocumented elements.
     * Useful for identifying classes and methods that haven't yet been documented.
     * @param    bool $undocumentedElementWarnings
     */
    
function setUndocumentedElementWarningsMode($undocumentedElementWarnings)
    {
        
$this->undocumentedElementWarnings $undocumentedElementWarnings;
    }

    
/**
     * set display of elements marked with @access private
     *
     * If set to true, elements will be displayed
     * @param    bool $parse
     */
    
function setParsePrivate($parse)
    {
        
$this->parsePrivate $parse;
    }
}

/** @access private */
function pagesort($a$b)
{
    return 
strnatcasecmp($a->parent->file,$b->parent->file);
}
?>

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0312 ]--