Source for file ProceduralPages.inc
Documentation is available at ProceduralPages.inc
* Intermediate procedural page parsing structure.
* This structure parses defines, functions, and global variables by file,
* and then iterates over the elements to document conflicts.
* phpDocumentor :: automatic documentation generator
* Copyright (c) 2002-2006 Gregory Beaver
* 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
* 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
* @copyright 2002-2006 Gregory Beaver
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version CVS: $Id: ProceduralPages.inc,v 1.4 2006/10/23 03:32:56 cellog Exp $
* @link http://www.phpdoc.org
* @link http://pear.php.net/PhpDocumentor
* Intermediate procedural page parsing structure.
* This structure parses defines, functions, and global variables by file,
* and then iterates over the elements to document conflicts.
* @version $Id: ProceduralPages.inc,v 1.4 2006/10/23 03:32:56 cellog Exp $
* file being parsed, used in every add function to match up elements with the file that contains them
* @see addClass(), addMethod(), addVar(), nextFile()
* array of all procedural pages ordered by name
* array(name => array(fullpath => parserPage,fullpath => parserPage2 [if there are name conflicts],...))
* array of all procedural pages ordered by name that have been ignored via -po or @access private or @ignore
* array(name => array(fullpath => parserPage,fullpath => parserPage2 [if there are name conflicts],...))
* array of all procedural page names ordered by full path to the file
* array(fullpath => name)
* array of parsed includes organized by the full path of the file that contains the include.
* array(full path => array(includename => {@link parserInclude}))
* array of parsed functions organized by the full path of the file that contains the function.
* array(full path => array(functionname => {@link parserFunction}))
* array of parsed defines organized by the full path of the file that contains the define.
* array(full path => array(definename => {@link parserDefine}))
* array of parsed global variables organized by the full path of the file that contains the global variable definition.
* array(full path => array(globalname => {@link parserGlobal}))
* array of file names organized by functions that are in the file.
* This structure is designed to handle name conflicts. Two files can contain functions with the same name, and this array will
* record both filenames to help control namespace errors
* array(functionname => array(full path of file containing functionname, full path of file 2 containing functionname...)
* array of file names organized by defines that are in the file.
* This structure is designed to handle name conflicts. Two files can contain defines with the same name, and this array will
* record both filenames to help control namespace errors
* array(definename => array(full path of file containing definename, full path of file 2 containing definename...)
* array of file names organized by global variables that are in the file.
* This structure is designed to handle name conflicts. Two files can contain global variables with the same name, and this array will
* record both filenames to help control namespace errors
* array(global variablename => array(full path of file containing global variablename, full path of file 2 containing global variablename...)
* array of packages ordered by full path
* array(fullpath => array(packagename,subpackagename))
* array of packages assigned to classes in a file, ordered by fullpath
* array(fullpath => array(packagename => array(subpackagename => 1,subpackagename => 1,..),packagename2 =>...)
* Namespace conflicts within all documented packages of functions
* array(functionname => array(full path, full path,...))
* Namespace conflicts within all documented pages
* array(pagename => array(fullpath, fullpath,...))
* Namespace conflicts within all documented packages of functions
* array(functionname => array(full path, full path,...))
* Namespace conflicts within all documented packages of functions
* array(functionname => array(full path, full path,...))
var $packagesetup = false;
* sets up the {@link $pages} array
* @param parserPage &$element
$this->curfile = $element->getPath();
$this->pages[$element->getFile()][$element->getPath()] = $element;
* moves a page from the {@link $pages} array to the {@link $ignorepages} array
* @param parserPage &$element
$this->ignorepages[$element->getFile()][$element->getPath()] = $this->pages[$element->getFile()][$element->getPath()];
unset ($this->pages[$element->getFile()][$element->getPath()]);
if (!isset ($this->pathpages[$path])) return false;
// fixes [ 1391432 ] Too many underscores in include links.
$p->name = $c->getPageName($p);
$info['package'] = $p->package;
$info['subpackage'] = $p->subpackage;
$info['name'] = $p->getFile();
$info['source_loc'] = $p->getSourceLocation($c);
$x->addLink($p->path,$p->name,$p->file,$p->package, $p->subpackage);
$info['docs'] = $c->returnSee($x);
* Change a page's name from its file to alias $name
* This function is used to handle a @name tag in a page-level DocBlock
* Changes the package of the page represented by $path
* changes package in both the {@link $pages} array and the {@link pagepackages} array
* @param string $path full path
* @param string $subpackage
$this->pages[$this->pathpages[$path]][$path]->subpackage = $subpackage;
$el->subpackage = $subpackage;
$el->subpackage = $subpackage;
$el->subpackage = $subpackage;
$el->subpackage = $subpackage;
* sets up the {@link $includesbyfile} array using {@link $curfile}
* @param parserInclude &$element
* sets up the {@link $functionsbyfile} array using {@link $curfile}
* @param parserFunction &$element
if ($function->getName() == $element->getName())
* sets up the {@link $globalsbyfile} array using {@link $curfile}
* @param parserGlobal &$element
if ($global->getName() == $element->getName())
* sets up the {@link $definesbyfile} array using {@link $curfile}
* @param parserDefine &$element
if ($define->getName() == $element->getName())
* Used to align an element with the package of its parent page prior to Conversion.
* @param parserElement &$element
if ($element->type == 'define')
if ($el->getName() == $element->getName())
} elseif ($element->type == 'global')
if ($el->getName() == $element->getName())
} elseif ($element->type == 'include')
if ($el->getName() == $element->getName())
} elseif ($element->type == 'function')
if ($el->getName() == $element->getName())
* adds a package from a class to the current file
* @param string $file full path to the file that contains the class
* @param string $package package name
// don't care about default
// if ($package == $GLOBALS['phpDocumentor_DefaultPackageName'])
// $this->revcpbf[$file][$package][$subpackage] = 1;
if (!isset ($this->revcpbf[$file][$package][$subpackage]))
$this->revcpbf[$file][$package][$subpackage] = 1;
* if there is one class package in a file, the parent path inherits the package if its package is default.
* helps with -po to avoid dumb bugs
if ($this->packagesetup) return;
if ($this->pagepackages[$fullpath][0] == $GLOBALS['phpDocumentor_DefaultPackageName'])
if (count($packages) == 1)
list ($package,$subpackage) = each($packages);
if (count($subpackage) == 1) list ($subpackage,) = each($subpackage);
$this->packagesetup = true;
* extracts function, define, and global variable name conflicts within the same package and between different
* packages. No two elements with the same name are allowed in the same package, to keep automatic linking
function setupConflicts(&$render)
// create a list of conflicting functions in each package
foreach($package as $pathpackages)
// if at least 2 functions exist in the same package, delete all but the first one and add warnings
if (count($pathpackages) - 1)
for($i= 1; $i < count($pathpackages); $i++ )
unset ($paths[$oth[$pathpackages[$i]]]);
// create a list of conflicting functions in each package
foreach($package as $pathpackages)
// if at least 2 functions exist in the same package, delete all but the first one and add warnings
if (count($pathpackages) - 1)
for($i= 1; $i < count($pathpackages); $i++ )
if ($this->definesbyfile[$pathpackages[$i]][$j]->getName() == $define)
unset ($paths[$oth[$pathpackages[$i]]]);
// create a list of conflicting functions in each package
foreach($package as $pathpackages)
// if at least 2 functions exist in the same package, delete all but the first one and add warnings
if (count($pathpackages) - 1)
for($i= 1; $i < count($pathpackages); $i++ )
if ($this->globalsbyfile[$pathpackages[$i]][$j]->getName() == $global)
unset ($paths[$oth[$pathpackages[$i]]]);
foreach($this->pages as $name => $pages)
* called by {@link parserFunction::getConflicts()} to get inter-package conflicts, should not be called directly
* @return array Format: (package => {@link parserFunction} of conflicting function)
function getFuncConflicts($name)
if ($func->getName() == $name)
* called by {@link parserGlobal::getConflicts()} to get inter-package conflicts, should not be called directly
* @return array Format: (package => {@link parserGlobal} of conflicting global variable)
function getGlobalConflicts($name)
if ($func->getName() == $name)
* called by {@link parserDefine::getConflicts()} to get inter-package conflicts, should not be called directly
* @return array Format: (package => {@link parserDefine} of conflicting define)
function getDefineConflicts($name)
if ($func->getName() == $name)
* Adjusts packages of all pages and removes name conflicts within a package
* Automatic linking requires that each linkable name have exactly one element associated with it. In other words, there
* cannot be two functions named foo() in the same package. This also adheres to php rules with one exception:
* define('whatever','this thing');
* define('whatever','this other thing');
* phpDocumentor is not aware of conditional control structures because it would slow things down considerably.
* So, what phpDocumentor does is automatically ignore the second define and raise a warning. The warning can
* be eliminated with an @ignore tag on the second element like so:
* define('whatever','this thing');
* define('whatever','this other thing');
* if there are two files that contain the same procedural elements in the same package (for example,
* a common configuration file common.php), they will also be ignored as if they were in the same file. The
* reasoning behind this is simple. A package is an indivisible set of files and classes that a user will
* include in their code. Name conflicts must be avoided to allow successful execution.
* This function also plays the all-important role of calling {@link phpDocumentor_IntermediateParser::addElementToPage()} in
* order to add processed elements to their pages for Conversion.
* @param phpDocumentor_IntermediateParser &$render
$this->setupConflicts($render);
// phpDocumentor_out("\nProcessing Procedural Pages\n\n");
// phpDocumentor_out("Processing $path\n");
$b = &$this->pages[$name][$path];
$render->addPage($b, $path);
$render->addUses($b, $path);
$include->docblock->package = $a[0];
$include->docblock->subpackage = $a[1];
$render->addElementToPage($include,$path);
$function->docblock->package = $a[0];
$function->docblock->subpackage = $a[1];
$render->addElementToPage($function,$path);
$render->addUses($function,$path);
$define->docblock->package = $a[0];
$define->docblock->subpackage = $a[1];
$render->addElementToPage($define,$path);
$render->addUses($define,$path);
$global->docblock->package = $a[0];
$global->docblock->subpackage = $a[1];
$render->addElementToPage($global,$path);
$render->addUses($global,$path);
$this->_parsedbase = $pbase;
* @return false|parserPagereturns matched parserPage if found
* @param string include() statement path to check
* @param string full path of file the statement is in
* @param string full path to base directory of parsing, used for .
* @return array|stringreturns an array of possible file locations or
* a string if there is an exact match
if (strpos($path,':') !== false)
{ // windows, and we have a drive letter
} elseif(strpos($path,'/') === 0)
} elseif ($path[0] == '..')
array_pop($dirfile); // remove the current directory
if (!count($dirfile)) return false; // we were at a top-level dir!
$path[0] = join($dirfile,'/'); // replace .. with parent dirname
|