home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / ProceduralPages.inc < prev    next >
Encoding:
Text File  |  2004-03-24  |  30.3 KB  |  782 lines

  1. <?php
  2. //
  3. // +------------------------------------------------------------------------+
  4. // | phpDocumentor                                                          |
  5. // +------------------------------------------------------------------------+
  6. // | Copyright (c) 2000-2003 Joshua Eichorn, Gregory Beaver                 |
  7. // | Email         jeichorn@phpdoc.org, cellog@phpdoc.org                   |
  8. // | Web           http://www.phpdoc.org                                    |
  9. // | Mirror        http://phpdocu.sourceforge.net/                          |
  10. // | PEAR          http://pear.php.net/package-info.php?pacid=137           |
  11. // +------------------------------------------------------------------------+
  12. // | This source file is subject to version 3.00 of the PHP License,        |
  13. // | that is available at http://www.php.net/license/3_0.txt.               |
  14. // | If you did not receive a copy of the PHP license and are unable to     |
  15. // | obtain it through the world-wide-web, please send a note to            |
  16. // | license@php.net so we can mail you a copy immediately.                 |
  17. // +------------------------------------------------------------------------+
  18. //
  19.  
  20. /**
  21.  * Intermediate procedural page parsing structure.
  22.  * This structure parses defines, functions, and global variables by file,
  23.  * and then iterates over the elements to document conflicts.
  24.  * @package phpDocumentor
  25.  * @author Greg Beaver <cellog@users.sourceforge.net>
  26.  * @since 1.1
  27.  * @version $Id: ProceduralPages.inc,v 1.28.2.5 2003/08/13 20:18:56 CelloG Exp $
  28.  */
  29. /**
  30.  * Intermediate procedural page parsing structure.
  31.  * This structure parses defines, functions, and global variables by file,
  32.  * and then iterates over the elements to document conflicts.
  33.  * @package phpDocumentor
  34.  * @author Greg Beaver <cellog@users.sourceforge.net>
  35.  * @since 1.1
  36.  * @version $Id: ProceduralPages.inc,v 1.28.2.5 2003/08/13 20:18:56 CelloG Exp $
  37.  */
  38. class ProceduralPages
  39. {
  40.     /**
  41.      * file being parsed, used in every add function to match up elements with the file that contains them
  42.      * @see addClass(), addMethod(), addVar(), nextFile()
  43.      * @var string
  44.      */
  45.     var $curfile;
  46.     /**
  47.      * array of all procedural pages ordered by name
  48.      * Format:
  49.      * array(name => array(fullpath => parserPage,fullpath => parserPage2 [if there are name conflicts],...))
  50.      * @var array
  51.      */
  52.     var $pages = array();
  53.     /**
  54.      * array of all procedural pages ordered by name that have been ignored via -po or @access private or @ignore
  55.      * Format:
  56.      * array(name => array(fullpath => parserPage,fullpath => parserPage2 [if there are name conflicts],...))
  57.      * @var array
  58.      */
  59.     var $ignorepages = array();
  60.     /**
  61.      * array of all procedural page names ordered by full path to the file
  62.      * Format:
  63.      * array(fullpath => name)
  64.      * @var array
  65.      */
  66.     var $pathpages = array();
  67.     /**
  68.      * array of parsed includes organized by the full path of the file that contains the include.
  69.      * Format:
  70.      * array(full path => array(includename => {@link parserInclude}))
  71.      * @var array
  72.      */
  73.     var $includesbyfile = array();
  74.     /**
  75.      * array of parsed functions organized by the full path of the file that contains the function.
  76.      * Format:
  77.      * array(full path => array(functionname => {@link parserFunction}))
  78.      * @var array
  79.      */
  80.     var $functionsbyfile = array();
  81.     /**
  82.      * array of parsed defines organized by the full path of the file that contains the define.
  83.      * Format:
  84.      * array(full path => array(definename => {@link parserDefine}))
  85.      * @var array
  86.      */
  87.     var $definesbyfile = array();
  88.     /**
  89.      * array of parsed global variables organized by the full path of the file that contains the global variable definition.
  90.      * Format:
  91.      * array(full path => array(globalname => {@link parserGlobal}))
  92.      * @var array
  93.      */
  94.     var $globalsbyfile = array();
  95.     /**
  96.      * array of file names organized by functions that are in the file.
  97.      * This structure is designed to handle name conflicts.  Two files can contain functions with the same name, and this array will
  98.      * record both filenames to help control namespace errors
  99.      * Format:
  100.      * array(functionname => array(full path of file containing functionname, full path of file 2 containing functionname...)
  101.      * @var array
  102.      */
  103.     var $functionsbynamefile = array();
  104.     /**
  105.      * array of file names organized by defines that are in the file.
  106.      * This structure is designed to handle name conflicts.  Two files can contain defines with the same name, and this array will
  107.      * record both filenames to help control namespace errors
  108.      * Format:
  109.      * array(definename => array(full path of file containing definename, full path of file 2 containing definename...)
  110.      * @var array
  111.      */
  112.     var $definesbynamefile = array();
  113.     /**
  114.      * array of file names organized by global variables that are in the file.
  115.      * This structure is designed to handle name conflicts.  Two files can contain global variables with the same name, and this array will
  116.      * record both filenames to help control namespace errors
  117.      * Format:
  118.      * array(global variablename => array(full path of file containing global variablename, full path of file 2 containing global variablename...)
  119.      * @var array
  120.      */
  121.     var $globalsbynamefile = array();
  122.     /**
  123.      * array of packages ordered by full path
  124.      * Format:
  125.      * array(fullpath => array(packagename,subpackagename))
  126.      * @var array
  127.      */
  128.     var $pagepackages = array();
  129.     /**
  130.      * array of packages assigned to classes in a file, ordered by fullpath
  131.      * Format:
  132.      * array(fullpath => array(packagename => array(subpackagename => 1,subpackagename => 1,..),packagename2 =>...)
  133.      * @var array
  134.      */
  135.     var $pageclasspackages = array();
  136.     /**
  137.      * Namespace conflicts within all documented packages of functions
  138.      * Format:
  139.      * array(functionname => array(full path, full path,...))
  140.      * @var array
  141.      */
  142.     var $functionconflicts = array();
  143.     /**
  144.      * Namespace conflicts within all documented pages
  145.      * Format:
  146.      * array(pagename => array(fullpath, fullpath,...))
  147.      * @var array
  148.      */
  149.     var $pageconflicts = array();
  150.     /**
  151.      * Namespace conflicts within all documented packages of functions
  152.      * Format:
  153.      * array(functionname => array(full path, full path,...))
  154.      * @var array
  155.      */
  156.     var $defineconflicts = array();
  157.     /**
  158.      * Namespace conflicts within all documented packages of functions
  159.      * Format:
  160.      * array(functionname => array(full path, full path,...))
  161.      * @var array
  162.      */
  163.     var $globalconflicts = array();
  164.     /** @access private
  165.      * @var array */
  166.     var $revcpbf = array();
  167.     /** @access private
  168.      * @var boolean */
  169.     var $packagesetup = false;
  170.  
  171.     /**
  172.      * sets up the {@link $pages} array
  173.      * @param parserPage &$element
  174.      */
  175.     function addPage(&$element)
  176.     {
  177.         $this->curfile = $element->getPath();
  178.         $this->pages[$element->getFile()][$element->getPath()] = $element;
  179.         $this->pathpages[$this->curfile] = $element->getFile();
  180.         $this->addPagePackage($this->curfile, $element->package, $element->subpackage);
  181.     }
  182.     
  183.     /**
  184.      * moves a page from the {@link $pages} array to the {@link $ignorepages} array
  185.      * @param parserPage &$element
  186.      */
  187.     function ignorePage(&$element)
  188.     {
  189.         $this->ignorepages[$element->getFile()][$element->getPath()] = $this->pages[$element->getFile()][$element->getPath()];
  190.         unset($this->pages[$element->getFile()][$element->getPath()]);
  191.     }
  192.  
  193.     function getPathInfo($path,&$c)
  194.     {
  195.         $path = str_replace('/',SMART_PATH_DELIMITER,$path);
  196.         $info = array();
  197.         if (!isset($this->pathpages[$path])) return false;
  198.         $p = $this->pages[$this->pathpages[$path]][$path];
  199.         $p->name = $c->getPageName($p);
  200.         $info['package'] = $p->package;
  201.         $info['subpackage'] = $p->subpackage;
  202.         $info['name'] = $p->getFile();
  203.         $info['source_loc'] = $p->getSourceLocation($c);
  204.         $x = new pageLink;
  205.         $x->addLink($p->path,$p->name,$p->file,$p->package, $p->subpackage);
  206.         $info['docs'] = $c->returnSee($x);
  207.         return $info;
  208.     }
  209.     
  210.     /**
  211.      * Change a page's name from its file to alias $name
  212.      *
  213.      * This function is used to handle a @name tag in a page-level DocBlock
  214.      * @param string $name
  215.      */
  216.     function setName($name)
  217.     {
  218.         $this->pages[$name][$this->curfile] = $this->pages[$this->pathpages[$this->curfile]][$this->curfile];
  219.         $this->pages[$name][$this->curfile]->file = $name;
  220.         unset($this->pages[$this->pathpages[$this->curfile]][$this->curfile]);
  221.         $this->pathpages[$this->curfile] = $name;
  222.     }
  223.     
  224.     /**
  225.      * Changes the package of the page represented by $path
  226.      *
  227.      * changes package in both the {@link $pages} array and the {@link pagepackages} array
  228.      * @param string $path full path
  229.      * @param string $package
  230.      * @param string $subpackage
  231.      */
  232.     function addPagePackage($path,$package,$subpackage)
  233.     {
  234.         $this->pages[$this->pathpages[$path]][$path]->package = $package;
  235.         $this->pages[$this->pathpages[$path]][$path]->subpackage = $subpackage;
  236.         $this->pagepackages[$path] = array($package, $subpackage);
  237.         if (isset($this->includesbyfile[$path]))
  238.         {
  239.             foreach($this->includesbyfile[$path] as $i => $el)
  240.             {
  241.                 $el->package = $package;
  242.                 $el->subpackage = $subpackage;
  243.                 $this->includesbyfile[$path][$i] = $el;
  244.             }
  245.         }
  246.         if (isset($this->functionsbyfile[$path]))
  247.         {
  248.             foreach($this->functionsbyfile[$path] as $i => $el)
  249.             {
  250.                 $el->package = $package;
  251.                 $el->subpackage = $subpackage;
  252.                 $this->functionsbyfile[$path][$i] = $el;
  253.             }
  254.         }
  255.         if (isset($this->definesbyfile[$path]))
  256.         {
  257.             foreach($this->definesbyfile[$path] as $i => $el)
  258.             {
  259.                 $el->package = $package;
  260.                 $el->subpackage = $subpackage;
  261.                 $this->definesbyfile[$path][$i] = $el;
  262.             }
  263.         }
  264.         if (isset($this->globalsbyfile[$path]))
  265.         {
  266.             foreach($this->globalsbyfile[$path] as $i => $el)
  267.             {
  268.                 $el->package = $package;
  269.                 $el->subpackage = $subpackage;
  270.                 $this->globalsbyfile[$path][$i] = $el;
  271.             }
  272.         }
  273.     }
  274.  
  275.     /**
  276.      * sets up the {@link $includesbyfile} array using {@link $curfile}
  277.      * @param parserInclude &$element
  278.      */
  279.     function addInclude(&$element)
  280.     {
  281.         $this->includesbyfile[$this->curfile][] = $element;
  282.     }
  283.  
  284.     /**
  285.      * sets up the {@link $functionsbyfile} array using {@link $curfile}
  286.      * @param parserFunction &$element
  287.      */
  288.     function addFunction(&$element)
  289.     {
  290.         if (isset($this->functionsbyfile[$this->curfile]))
  291.         {
  292.             foreach($this->functionsbyfile[$this->curfile] as $i => $function)
  293.             {
  294.                 if ($function->getName() == $element->getName())
  295.                 {
  296.                     addWarning(PDERROR_ELEMENT_IGNORED,'function',$element->getName(),$this->curfile);
  297.                     return;
  298.                 }
  299.             }
  300.         }
  301.         $this->functionsbyfile[$this->curfile][] = $element;
  302.         $this->functionsbynamefile[$element->getName()][] = $this->curfile;
  303.     }
  304.  
  305.     /**
  306.      * sets up the {@link $globalsbyfile} array using {@link $curfile}
  307.      * @param parserGlobal &$element
  308.      */
  309.     function addGlobal(&$element)
  310.     {
  311.         if (isset($this->globalsbyfile[$this->curfile]))
  312.         {
  313.             foreach($this->globalsbyfile[$this->curfile] as $i => $global)
  314.             {
  315.                 if ($global->getName() == $element->getName())
  316.                 {
  317.                     addWarning(PDERROR_ELEMENT_IGNORED,'global variable',$element->getName(),$this->curfile);
  318.                     return;
  319.                 }
  320.             }
  321.         }
  322.         $this->globalsbyfile[$this->curfile][] = $element;
  323.         $this->globalsbynamefile[$element->getName()][] = $this->curfile;
  324.     }
  325.  
  326.     /**
  327.      * sets up the {@link $definesbyfile} array using {@link $curfile}
  328.      * @param parserDefine &$element
  329.      */
  330.     function addDefine(&$element)
  331.     {
  332.         if (isset($this->definesbyfile[$this->curfile]))
  333.         {
  334.             foreach($this->definesbyfile[$this->curfile] as $i => $define)
  335.             {
  336.                 if ($define->getName() == $element->getName())
  337.                 {
  338.                     addWarning(PDERROR_ELEMENT_IGNORED,'define',$element->getName(),$this->curfile);
  339.                     return;
  340.                 }
  341.             }
  342.         }
  343.         $this->definesbyfile[$this->curfile][] = $element;
  344.         $this->definesbynamefile[$element->getName()][] = $this->curfile;
  345.     }
  346.     
  347.     /**
  348.      * Used to align an element with the package of its parent page prior to Conversion.
  349.      * @param parserElement &$element
  350.      */
  351.     function replaceElement(&$element)
  352.     {
  353.         if ($element->type == 'define')
  354.         {
  355.             foreach($this->definesbyfile[$element->getPath()] as $i => $el)
  356.             {
  357.                 if ($el->getName() == $element->getName())
  358.                 {
  359.                     $this->definesbyfile[$element->getPath()][$i] = &$element;
  360.                 }
  361.             }
  362.         } elseif ($element->type == 'global')
  363.         {
  364.             foreach($this->globalsbyfile[$element->getPath()] as $i => $el)
  365.             {
  366.                 if ($el->getName() == $element->getName())
  367.                 {
  368.                     $this->globalsbyfile[$element->getPath()][$i] = &$element;
  369.                 }
  370.             }
  371.         } elseif ($element->type == 'include')
  372.         {
  373.             foreach($this->includesbyfile[$element->getPath()] as $i => $el)
  374.             {
  375.                 if ($el->getName() == $element->getName())
  376.                 {
  377.                     $this->includesbyfile[$element->getPath()][$i] = &$element;
  378.                 }
  379.             }
  380.         } elseif ($element->type == 'function')
  381.         {
  382.             foreach($this->functionsbyfile[$element->getPath()] as $i => $el)
  383.             {
  384.                 if ($el->getName() == $element->getName())
  385.                 {
  386.                     $this->functionsbyfile[$element->getPath()][$i] = &$element;
  387.                 }
  388.             }
  389.         }
  390.     }
  391.  
  392.     /**
  393.      * adds a package from a class to the current file
  394.      * @param string $file    full path to the file that contains the class
  395.      * @param string $package package name
  396.      */
  397.     function addClassPackageToFile($file,$package,$subpackage)
  398.     {
  399.         // don't care about default
  400. //        if ($package == $GLOBALS['phpDocumentor_DefaultPackageName'])
  401. //        $this->revcpbf[$file][$package][$subpackage] = 1;
  402.         if (!isset($this->revcpbf[$file][$package][$subpackage]))
  403.         {
  404.             $this->pageclasspackages[$file][$package][$subpackage] = 1;
  405.         }
  406.         $this->revcpbf[$file][$package][$subpackage] = 1;
  407.     }
  408.     
  409.     /**
  410.      * if there is one class package in a file, the parent path inherits the package if its package is default.
  411.      * helps with -po to avoid dumb bugs
  412.      */
  413.     function setupPagePackages()
  414.     {
  415.         if ($this->packagesetup) return;
  416.         foreach($this->pageclasspackages as $fullpath => $packages)
  417.         {
  418.             if (isset($this->pagepackages[$fullpath]))
  419.             {
  420.                 if ($this->pagepackages[$fullpath][0] == $GLOBALS['phpDocumentor_DefaultPackageName'])
  421.                 {
  422.                     if (count($packages) == 1)
  423.                     {
  424.                         list($package,$subpackage) = each($packages);
  425.                         if (count($subpackage) == 1) list($subpackage,) = each($subpackage);
  426.                         else $subpackage = '';
  427.                         $this->addPagePackage($fullpath,$package,$subpackage);
  428.                     }
  429.                 }
  430.             }
  431.         }
  432.         $this->packagesetup = true;
  433.     }
  434.     
  435.     /**
  436.      * extracts function, define, and global variable name conflicts within the same package and between different
  437.      * packages.  No two elements with the same name are allowed in the same package, to keep automatic linking 
  438.      * possible.
  439.      * @access private
  440.      */
  441.     function setupConflicts(&$render)
  442.     {
  443.         
  444.         foreach($this->functionsbynamefile as $function => $paths)
  445.         {
  446.             if (count($paths) - 1)
  447.             { //conflict
  448.                 $package = array();
  449.                 foreach($paths as $path)
  450.                 {
  451.                     // create a list of conflicting functions in each package
  452.                     $package[$this->pagepackages[$path][0]][] = $path;
  453.                 }
  454.                 foreach($package as $pathpackages)
  455.                 {
  456.                     // if at least 2 functions exist in the same package, delete all but the first one and add warnings
  457.                     if (count($pathpackages) - 1)
  458.                     {
  459.                         for($i=1; $i < count($pathpackages); $i++)
  460.                         {
  461.                             addWarning(PDERROR_ELEMENT_IGNORED,'function',$function,$pathpackages[$i]);
  462.                             foreach($this->functionsbyfile[$pathpackages[$i]] as $j => $blah)
  463.                             {
  464.                                 if ($this->functionsbyfile[$pathpackages[$i]][$j]->getName() == $function)
  465.                                 unset($this->functionsbyfile[$pathpackages[$i]][$j]);
  466.                             }
  467.                             $oth = array_flip($paths);
  468.                             unset($paths[$oth[$pathpackages[$i]]]);
  469.                         }
  470.                     }
  471.                 }
  472.                 $this->functionconflicts[$function] = $paths;
  473.             }
  474.         }
  475.  
  476.         foreach($this->definesbynamefile as $define => $paths)
  477.         {
  478.             if (count($paths) - 1)
  479.             { //conflict
  480.                 $package = array();
  481.                 foreach($paths as $path)
  482.                 {
  483.                     // create a list of conflicting functions in each package
  484.                     $package[$this->pagepackages[$path][0]][] = $path;
  485.                 }
  486.                 foreach($package as $pathpackages)
  487.                 {
  488.                     // if at least 2 functions exist in the same package, delete all but the first one and add warnings
  489.                     if (count($pathpackages) - 1)
  490.                     {
  491.                         for($i=1; $i < count($pathpackages); $i++)
  492.                         {
  493.                             addWarning(PDERROR_ELEMENT_IGNORED,'define',$define,$pathpackages[$i]);
  494.                             foreach($this->definesbyfile[$pathpackages[$i]] as $j => $blah)
  495.                             {
  496.                                 if ($this->definesbyfile[$pathpackages[$i]][$j]->getName() == $define)
  497.                                 unset($this->definesbyfile[$pathpackages[$i]][$j]);
  498.                             }
  499.                             $oth = array_flip($paths);
  500.                             unset($paths[$oth[$pathpackages[$i]]]);
  501.                         }
  502.                     }
  503.                 }
  504.                 $this->defineconflicts[$define] = $paths;
  505.             }
  506.         }
  507.  
  508.         foreach($this->globalsbynamefile as $global => $paths)
  509.         {
  510.             if (count($paths) - 1)
  511.             { //conflict
  512.                 $package = array();
  513.                 foreach($paths as $path)
  514.                 {
  515.                     // create a list of conflicting functions in each package
  516.                     $package[$this->pagepackages[$path][0]][] = $path;
  517.                 }
  518.                 foreach($package as $pathpackages)
  519.                 {
  520.                     // if at least 2 functions exist in the same package, delete all but the first one and add warnings
  521.                     if (count($pathpackages) - 1)
  522.                     {
  523.                         for($i=1; $i < count($pathpackages); $i++)
  524.                         {
  525.                             addWarning(PDERROR_ELEMENT_IGNORED,'global variable',$global,$pathpackages[$i]);
  526.                             foreach($this->globalsbyfile[$pathpackages[$i]] as $j => $blah)
  527.                             {
  528.                                 if ($this->globalsbyfile[$pathpackages[$i]][$j]->getName() == $global)
  529.                                 unset($this->globalsbyfile[$pathpackages[$i]][$j]);
  530.                             }
  531.                             $oth = array_flip($paths);
  532.                             unset($paths[$oth[$pathpackages[$i]]]);
  533.                         }
  534.                     }
  535.                 }
  536.                 $this->globalconflicts[$global] = $paths;
  537.             }
  538.         }
  539.         
  540.         foreach($this->pages as $name => $pages)
  541.         {
  542.             if (count($pages) - 1)
  543.             { // possible conflict
  544.                 
  545.             }
  546.         }
  547.     }
  548.     
  549.     /**
  550.      * called by {@link parserFunction::getConflicts()} to get inter-package conflicts, should not be called directly
  551.      * @access private
  552.      * @return array Format: (package => {@link parserFunction} of conflicting function)
  553.      */
  554.     function getFuncConflicts($name)
  555.     {
  556.         if (!isset($this->functionconflicts[$name])) return false;
  557.         $a = array();
  558.         foreach($this->functionconflicts[$name] as $conflict)
  559.         {
  560.             foreach($this->functionsbyfile[$conflict] as $i => $func)
  561.             {
  562.                 if ($func->getName() == $name)
  563.                 $a[$this->functionsbyfile[$conflict][$i]->docblock->package] = $this->functionsbyfile[$conflict][$i];
  564.             }
  565.         }
  566.         return $a;
  567.     }
  568.     
  569.     /**
  570.      * called by {@link parserGlobal::getConflicts()} to get inter-package conflicts, should not be called directly
  571.      * @access private
  572.      * @return array Format: (package => {@link parserGlobal} of conflicting global variable)
  573.      */
  574.     function getGlobalConflicts($name)
  575.     {
  576.         if (!isset($this->globalconflicts[$name])) return false;
  577.         $a = array();
  578.         foreach($this->globalconflicts[$name] as $conflict)
  579.         {
  580.             foreach($this->globalsbyfile[$conflict] as $i => $func)
  581.             {
  582.                 if ($func->getName() == $name)
  583.                 $a[$this->globalsbyfile[$conflict][$i]->docblock->package] = $this->globalsbyfile[$conflict][$i];
  584.             }
  585.         }
  586.         return $a;
  587.     }
  588.     
  589.     /**
  590.      * called by {@link parserDefine::getConflicts()} to get inter-package conflicts, should not be called directly
  591.      * @access private
  592.      * @return array Format: (package => {@link parserDefine} of conflicting define)
  593.      */
  594.     function getDefineConflicts($name)
  595.     {
  596.         if (!isset($this->defineconflicts[$name])) return false;
  597.         $a = array();
  598.         foreach($this->defineconflicts[$name] as $conflict)
  599.         {
  600.             foreach($this->definesbyfile[$conflict] as $i => $func)
  601.             {
  602.                 if ($func->getName() == $name)
  603.                 $a[$this->definesbyfile[$conflict][$i]->docblock->package] = $this->definesbyfile[$conflict][$i];
  604.             }
  605.         }
  606.         return $a;
  607.     }
  608.     
  609.     /**
  610.      * Adjusts packages of all pages and removes name conflicts within a package
  611.      *
  612.      * Automatic linking requires that each linkable name have exactly one element associated with it.  In other words, there
  613.      * cannot be two functions named foo() in the same package.  This also adheres to php rules with one exception:
  614.      *
  615.      * <code>
  616.      * if ($test == 3)
  617.      * {
  618.      *    define('whatever','this thing');
  619.      * } else
  620.      * {
  621.      *    define('whatever','this other thing');
  622.      * }
  623.      * </code>
  624.      *
  625.      * phpDocumentor is not aware of conditional control structures because it would slow things down considerably.
  626.      * So, what phpDocumentor does is automatically ignore the second define and raise a warning.  The warning can
  627.      * be eliminated with an @ignore tag on the second element like so:
  628.      *
  629.      * <code>
  630.      * if ($test == 3)
  631.      * {
  632.      *    define('whatever','this thing');
  633.      * } else
  634.      * {
  635.      *    /** @ignore {@*}
  636.      *    define('whatever','this other thing');
  637.      * }
  638.      * </code>
  639.      *
  640.      * if there are two files that contain the same procedural elements in the same package (for example, 
  641.      * a common configuration file common.php), they will also be ignored as if they were in the same file.  The
  642.      * reasoning behind this is simple.  A package is an indivisible set of files and classes that a user will
  643.      * include in their code.  Name conflicts must be avoided to allow successful execution.
  644.      *
  645.      * This function also plays the all-important role of calling {@link phpDocumentor_IntermediateParser::addElementToPage()} in
  646.      * order to add processed elements to their pages for Conversion.
  647.      * @param phpDocumentor_IntermediateParser &$render
  648.      */
  649.     function setupPages(&$render)
  650.     {
  651.         global $_phpDocumentor_setting;
  652.         phpDocumentor_out("\nProcessing Procedural Page Element Name Conflicts\n\n");
  653.         flush();
  654.         $this->setupPagePackages();
  655.         $this->setupConflicts($render);
  656. //        phpDocumentor_out("\nProcessing Procedural Pages\n\n");
  657.         foreach($this->pathpages as $path => $name)
  658.         {
  659. //            phpDocumentor_out("Processing $path\n");
  660.             $a = $this->pagepackages[$path];
  661.             $b = &$this->pages[$name][$path];
  662.             $render->addPage($b, $path);
  663.             $render->addUses($b, $path);
  664.             if (isset($this->includesbyfile[$path]))
  665.             foreach($this->includesbyfile[$path] as $include)
  666.             {
  667.                 $include->docblock->package = $a[0];
  668.                 $include->docblock->subpackage = $a[1];
  669.                 $render->addElementToPage($include,$path);
  670.             }
  671.     
  672.             if (isset($this->functionsbyfile[$path]))
  673.             foreach($this->functionsbyfile[$path] as $function)
  674.             {
  675.                 $function->docblock->package = $a[0];
  676.                 $function->docblock->subpackage = $a[1];
  677.                 $render->addElementToPage($function,$path);
  678.                 $render->addUses($function,$path);
  679.             }
  680.     
  681.             if (isset($this->definesbyfile[$path]))
  682.             foreach($this->definesbyfile[$path] as $define)
  683.             {
  684.                 $define->docblock->package = $a[0];
  685.                 $define->docblock->subpackage = $a[1];
  686.                 $render->addElementToPage($define,$path);
  687.                 $render->addUses($define,$path);
  688.             }
  689.     
  690.             if (isset($this->globalsbyfile[$path]))
  691.             foreach($this->globalsbyfile[$path] as $global)
  692.             {
  693.                 $global->docblock->package = $a[0];
  694.                 $global->docblock->subpackage = $a[1];
  695.                 $render->addElementToPage($global,$path);
  696.                 $render->addUses($global,$path);
  697.             }
  698.         }
  699.     }
  700.     
  701.     function setParseBase($pbase)
  702.     {
  703.         $this->_parsedbase = $pbase;
  704.     }
  705.     
  706.     /**
  707.      * @return false|parserPage returns matched parserPage if found
  708.      */
  709.     function pathMatchesParsedFile($path, $infile)
  710.     {
  711.         $test = $this->getRealPath($path, $infile);
  712.         if (is_string($test))
  713.         {
  714.             if (isset($this->pathpages[$test]))
  715.                 return $this->pages[$this->pathpages[$test]][$test];
  716.             if (PHPDOCUMENTOR_WINDOWS) $test = str_replace('/','\\',$test);
  717.             if (isset($this->pathpages[$test]))
  718.             {
  719.                 $a = $this->pages[$this->pathpages[$test]][$test];
  720.                 if (is_array($a->packageOutput) && !in_array($a->package, $a->packageOutput))
  721.                     return false;
  722.                 return $this->pages[$this->pathpages[$test]][$test];
  723.             }
  724.         } else
  725.         {
  726.             foreach($test as $file)
  727.             {
  728.                 if (isset($this->pathpages[$file]))
  729.                     return $this->pages[$this->pathpages[$file]][$file];
  730.                 if (PHPDOCUMENTOR_WINDOWS) $file = str_replace('/','\\',$file);
  731.                 if (isset($this->pathpages[$file]))
  732.                 {
  733.                     $a = $this->pages[$this->pathpages[$file]][$file];
  734.                     if (is_array($a->packageOutput) && !in_array($a->package, $a->packageOutput))
  735.                         return false;
  736.                     return $this->pages[$this->pathpages[$file]][$file];
  737.                 }
  738.             }
  739.         }
  740.         return false;
  741.     }
  742.     
  743.     /**
  744.      * @param string include() statement path to check
  745.      * @param string full path of file the statement is in
  746.      * @param string full path to base directory of parsing, used for .
  747.      * @return array|string returns an array of possible file locations or
  748.      *                      a string if there is an exact match
  749.      */
  750.     function getRealPath($path, $file)
  751.     {
  752.         $curdir = str_replace('\\','/',dirname($file));
  753.         $path = str_replace('\\','/',$path);
  754.         if (strpos($path,':') !== false)
  755.         { // windows, and we have a drive letter
  756.             return $path;
  757.         } elseif(strpos($path,'/') === 0)
  758.         {
  759.             return $path;
  760.         }
  761.         // not an absolute path
  762.         $path = explode('/',$path);
  763.         if ($path[0] == '.')
  764.         {
  765.             $path[0] = dirname($file);
  766.             return join($path,'/');
  767.         } elseif ($path[0] == '..')
  768.         {
  769.             $dirfile = explode('/',dirname(str_replace('\\','/',$file)));
  770.             array_pop($dirfile); // remove the current directory
  771.             if (!count($dirfile)) return false; // we were at a top-level dir!
  772.             $path[0] = join($dirfile,'/'); // replace .. with parent dirname
  773.             return join($path,'/');
  774.         } else
  775.         {
  776.             $path = join($path,'/');
  777.             return array($curdir . PATH_DELIMITER . $path,
  778.                          str_replace('\\','/',PHPDOCUMENTOR_BASE) . PATH_DELIMITER . $path);
  779.         }
  780.     }
  781. }
  782. ?>