From: Greg Beaver Date: Mon, 25 Oct 2004 17:14:34 +0000 (+0000) Subject: sync with PEAR_1_3 branch of pear-core X-Git-Tag: php-5.0.3RC1~127 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01ba76a2ed00d3500042d1a0d7f71c6b4e8b62a0;p=php sync with PEAR_1_3 branch of pear-core --- diff --git a/pear/PEAR/Builder.php b/pear/PEAR/Builder.php index 4806155ef5..c6b4a4f248 100644 --- a/pear/PEAR/Builder.php +++ b/pear/PEAR/Builder.php @@ -198,7 +198,7 @@ class PEAR_Builder extends PEAR_Common $dir = getcwd(); $this->log(2, "building in $dir"); $this->current_callback = $callback; - putenv('PATH=' . getenv('PATH') . ':' . $this->config->get('bin_dir')); + putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH')); $err = $this->_runCommand("phpize", array(&$this, 'phpizeCallback')); if (PEAR::isError($err)) { return $err; diff --git a/pear/PEAR/Command/Install.php b/pear/PEAR/Command/Install.php index f804a838e3..7a89c7cddd 100644 --- a/pear/PEAR/Command/Install.php +++ b/pear/PEAR/Command/Install.php @@ -303,7 +303,13 @@ package if needed. $downloaded = $this->downloader->getDownloadedPackages(); $this->installer->sortPkgDeps($downloaded); foreach ($downloaded as $pkg) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->install($pkg['file'], $options, $this->config); + PEAR::popErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData('ERROR: ' .$info->getMessage()); + continue; + } if (is_array($info)) { if ($this->config->get('verbose') > 0) { $label = "$info[package] $info[version]"; diff --git a/pear/PEAR/Command/Package.php b/pear/PEAR/Command/Package.php index dcdc86bd1a..d0aca3f8e5 100644 --- a/pear/PEAR/Command/Package.php +++ b/pear/PEAR/Command/Package.php @@ -155,7 +155,12 @@ use the "slide" option to move the release tag. 'summary' => 'Run Regression Tests', 'function' => 'doRunTests', 'shortcut' => 'rt', - 'options' => array(), + 'options' => array( + 'recur' => array( + 'shortopt' => 'r', + 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', + ) + ), 'doc' => '[testfile|dir ...] Run regression tests with PHP\'s regression testing script (run-tests.php).', ), @@ -250,6 +255,9 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm { $this->output = ''; include_once 'PEAR/Packager.php'; + if (sizeof($params) < 1) { + $params[0] = "package.xml"; + } $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; $packager =& new PEAR_Packager(); $err = $warn = array(); @@ -264,12 +272,6 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm if (isset($options['showname'])) { $this->output = $result; } - /* (cox) What is supposed to do that code? - $lines = explode("\n", $this->output); - foreach ($lines as $line) { - $this->output .= $line."n"; - } - */ if (PEAR::isError($result)) { $this->output .= "Package failed: ".$result->getMessage(); } @@ -434,6 +436,31 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm function doRunTests($command, $options, $params) { + include_once 'PEAR/RunTest.php'; + $log = new PEAR_Common; + $run = new PEAR_RunTest($log); + $tests = array(); + if (isset($options['recur'])) { + $depth = 4; + } else { + $depth = 1; + } + foreach ($params as $p) { + if (is_dir($p)) { + $dir = System::find(array($p, '-type', 'f', + '-maxdepth', $depth, + '-name', '*.phpt')); + $tests = array_merge($tests, $dir); + } else { + $tests[] = $p; + } + } + foreach ($tests as $t) { + $run->run($t); + } + + return true; + /* $cwd = getcwd(); $php = $this->config->get('php_bin'); putenv("TEST_PHP_EXECUTABLE=$php"); @@ -463,6 +490,7 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm system($cmd); } return true; + */ } // }}} @@ -642,6 +670,7 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm if (!isset($attr['role'])) { continue; } + $name = preg_replace('![/:\\\\]!', '/', $name); if ($attr['role'] == 'doc') { $info['doc_files'] .= " $name"; diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index 2f9c611823..3449ffaac3 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -34,7 +34,7 @@ define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/'); // this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 -define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-z]+\d*)?'); +define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '$/i'); // XXX far from perfect :-) @@ -98,7 +98,9 @@ $GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'p // }}} /** - * Class providing common functionality for PEAR adminsitration classes. + * Class providing common functionality for PEAR administration classes. + * @deprecated This class will disappear, and its components will be spread + * into smaller classes, like the AT&T breakup */ class PEAR_Common extends PEAR { @@ -142,12 +144,6 @@ class PEAR_Common extends PEAR * @access private */ var $_validPackageFile; - /** - * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} - * @var array - * @access private - */ - var $_packageSortTree; // }}} @@ -1293,6 +1289,15 @@ class PEAR_Common extends PEAR if (!function_exists("token_get_all")) { return false; } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } if (!$fp = @fopen($file, "r")) { return false; } @@ -1315,17 +1320,21 @@ class PEAR_Common extends PEAR $brace_level = 0; $lastphpdoc = ''; $current_class = ''; + $current_interface = ''; $current_class_level = -1; $current_function = ''; $current_function_level = -1; $declared_classes = array(); + $declared_interfaces = array(); $declared_functions = array(); $declared_methods = array(); $used_classes = array(); $used_functions = array(); $extends = array(); + $implements = array(); $nodeps = array(); $inquote = false; + $interface = false; for ($i = 0; $i < sizeof($tokens); $i++) { if (is_array($tokens[$i])) { list($token, $data) = $tokens[$i]; @@ -1341,6 +1350,14 @@ class PEAR_Common extends PEAR } } switch ($token) { + case T_WHITESPACE: + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; case '"': $inquote = true; break; @@ -1362,6 +1379,8 @@ class PEAR_Common extends PEAR case ']': $bracket_level--; continue 2; case '(': $paren_level++; continue 2; case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; case T_CLASS: if (($current_class_level != -1) || ($current_function_level != -1)) { PEAR::raiseError("Parser error: Invalid PHP file $file", @@ -1371,19 +1390,38 @@ class PEAR_Common extends PEAR case T_FUNCTION: case T_NEW: case T_EXTENDS: + case T_IMPLEMENTS: $look_for = $token; continue 2; case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'clone', 'throw') + )) { + PEAR::raiseError('Error: PHP5 packages must be packaged by php 5 PEAR'); + return false; + } + } if ($look_for == T_CLASS) { $current_class = $data; $current_class_level = $brace_level; $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; } elseif ($look_for == T_EXTENDS) { $extends[$current_class] = $data; } elseif ($look_for == T_FUNCTION) { if ($current_class) { $current_function = "$current_class::$data"; $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; } else { $current_function = $data; $declared_functions[] = $current_function; @@ -1398,6 +1436,7 @@ class PEAR_Common extends PEAR case T_VARIABLE: $look_for = 0; continue 2; + case T_DOC_COMMENT: case T_COMMENT: if (preg_match('!^/\*\*\s!', $data)) { $lastphpdoc = $data; @@ -1422,10 +1461,12 @@ class PEAR_Common extends PEAR return array( "source_file" => $file, "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, "declared_methods" => $declared_methods, "declared_functions" => $declared_functions, "used_classes" => array_diff(array_keys($used_classes), $nodeps), "inheritance" => $extends, + "implements" => $implements, ); } diff --git a/pear/PEAR/Downloader.php b/pear/PEAR/Downloader.php index 17ad4566a1..793cc0410e 100644 --- a/pear/PEAR/Downloader.php +++ b/pear/PEAR/Downloader.php @@ -381,7 +381,8 @@ class PEAR_Downloader extends PEAR_Common // there are no dependencies continue; } - foreach($alldeps as $info) { + $fail = false; + foreach ($alldeps as $info) { if ($info['type'] != 'pkg') { continue; } @@ -389,11 +390,18 @@ class PEAR_Downloader extends PEAR_Common if ($ret === false) { continue; } + if ($ret === 0) { + $fail = true; + continue; + } if (PEAR::isError($ret)) { return $ret; } $deppackages[] = $ret; } // foreach($alldeps + if ($fail) { + $deppackages = array(); + } } if (count($deppackages)) { @@ -561,7 +569,7 @@ class PEAR_Downloader extends PEAR_Common $savestate = array_shift($get); $this->pushError( "Release for '$package' dependency '$info[name]' " . "has state '$savestate', requires '$state'"); - return false; + return 0; } if (in_array(strtolower($info['name']), $this->_toDownload) || isset($mywillinstall[strtolower($info['name'])])) { diff --git a/pear/PEAR/ErrorStack.php b/pear/PEAR/ErrorStack.php index 6f44f4d686..329e076a6e 100644 --- a/pear/PEAR/ErrorStack.php +++ b/pear/PEAR/ErrorStack.php @@ -35,8 +35,11 @@ * * Since version 0.3alpha, it is possible to specify the exception class * returned from {@link push()} + * + * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can + * still be done quite handily in an error callback or by manipulating the returned array * @author Greg Beaver - * @version 0.6alpha + * @version PEAR1.3.2 (beta) * @package PEAR_ErrorStack * @category Debugging * @license http://www.php.net/license/3_0.txt PHP License v3.0 @@ -220,13 +223,6 @@ class PEAR_ErrorStack { */ var $_logger = false; - /** - * Class name to use for a PHP 5 exception that will be returned - * @var string - * @access protected - */ - var $_exceptionClass = 'Exception'; - /** * Error messages - designed to be overridden * @var array @@ -242,20 +238,14 @@ class PEAR_ErrorStack { * @param callback $contextCallback callback used for context generation, * defaults to {@link getFileLine()} * @param boolean $throwPEAR_Error - * @param string $exceptionClass exception class to instantiate if - * in PHP 5 */ function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false, $exceptionClass = null) + $throwPEAR_Error = false) { $this->_package = $package; $this->setMessageCallback($msgCallback); $this->setContextCallback($contextCallback); $this->_compat = $throwPEAR_Error; - // this allows child classes to simply redefine $this->_exceptionClass - if (!is_null($exceptionClass)) { - $this->_exceptionClass = $exceptionClass; - } } /** @@ -268,29 +258,27 @@ class PEAR_ErrorStack { * @param callback $contextCallback callback used for context generation, * defaults to {@link getFileLine()} * @param boolean $throwPEAR_Error - * @param string $exceptionClass exception class to instantiate if - * in PHP 5 * @param string $stackClass class to instantiate * @static * @return PEAR_ErrorStack */ function &singleton($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false, $exceptionClass = null, - $stackClass = 'PEAR_ErrorStack') + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') { if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } if (!class_exists($stackClass)) { - $trace = debug_backtrace(); + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, 'exception', array('stackclass' => $stackClass), 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', false, $trace); } return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = - &new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error, - $exceptionClass); + &new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); } /** @@ -383,12 +371,16 @@ class PEAR_ErrorStack { /** * Set an error code => error message mapping callback * - * This method sets the callback that can be used to generate error - * messages for any PEAR_ErrorStack instance - * @param array|string Callback function/method + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method */ function setContextCallback($contextCallback) { + if ($contextCallback === null) { + return $this->_contextCallback = false; + } if (!$contextCallback) { $this->_contextCallback = array(&$this, 'getFileLine'); } else { @@ -504,7 +496,7 @@ class PEAR_ErrorStack { * 'time' => time(), * 'context' => $context, * 'message' => $msg, - * //['repackage' => $err] repackaged error array + * //['repackage' => $err] repackaged error array/Exception class * ); * */ @@ -538,8 +530,7 @@ class PEAR_ErrorStack { $msg = call_user_func_array($this->_msgCallback, array(&$this, $err)); $err['message'] = $msg; - } - + } if ($repackage) { $err['repackage'] = $repackage; @@ -588,15 +579,6 @@ class PEAR_ErrorStack { if ($this->_compat && $push) { return $this->raiseError($msg, $code, null, null, $err); } - if (class_exists($this->_exceptionClass)) { - $exception = $this->_exceptionClass; - if (is_string($msg) && is_numeric($code)) { - $code = $code + 0; - } - $ret = new $exception($msg, $code); - $ret->errorData = $err; - return $ret; - } return $err; } @@ -630,7 +612,9 @@ class PEAR_ErrorStack { $s = &PEAR_ErrorStack::singleton($package); if ($s->_contextCallback) { if (!$backtrace) { - $backtrace = debug_backtrace(); + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } } } return $s->push($code, $level, $params, $msg, $repackage, $backtrace); @@ -757,7 +741,7 @@ class PEAR_ErrorStack { /** * Get a list of all errors since last purge, organized by package * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be - * @param boolean $clearStack Set to purge the error stack of existing errors + * @param boolean $purge Set to purge the error stack of existing errors * @param string $level Set to a level name in order to retrieve only errors of a particular level * @param boolean $merge Set to return a flat array, not organized by package * @param array $sortfunc Function used to sort a merged array - default diff --git a/pear/PEAR/Exception.php b/pear/PEAR/Exception.php index 8322fd034a..a5be021a97 100644 --- a/pear/PEAR/Exception.php +++ b/pear/PEAR/Exception.php @@ -15,24 +15,29 @@ // +----------------------------------------------------------------------+ // | Authors: Tomas V.V.Cox | // | Hans Lellelid | -// | | +// | Bertrand Mansion | +// | Greg Beaver | // +----------------------------------------------------------------------+ // // $Id$ -define('PEAR_OBSERVER_PRINT', -2); -define('PEAR_OBSERVER_TRIGGER', -4); -define('PEAR_OBSERVER_DIE', -8); /** * Base PEAR_Exception Class * + * WARNING: This code should be considered stable, but the API is + * subject to immediate and drastic change, so API stability is + * at best alpha + * * 1) Features: * * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) * - Definable triggers, shot when exceptions occur * - Pretty and informative error messages - * - Added more context info avaible (like class, method or cause) + * - Added more context info available (like class, method or cause) + * - cause can be a PEAR_Exception or an array of mixed + * PEAR_Exceptions/PEAR_ErrorStack warnings + * - callbacks for specific exception classes and their children * * 2) Ideas: * @@ -54,8 +59,8 @@ define('PEAR_OBSERVER_DIE', -8); * getCode * getFile * getLine - * getTrace - * getTraceAsString + * getTraceSafe + * getTraceSafeAsString * __toString * * 5) Usage example @@ -88,16 +93,18 @@ define('PEAR_OBSERVER_DIE', -8); * @version $Revision$ * @author Tomas V.V.Cox * @author Hans Lellelid + * @author Bertrand Mansion * */ class PEAR_Exception extends Exception { + const OBSERVER_PRINT = -2; + const OBSERVER_TRIGGER = -4; + const OBSERVER_DIE = -8; protected $cause; - protected $error_class; - protected $error_method; - - private $_method; private static $_observers = array(); + private static $_uniqueid = 0; + private $_trace; /** * Supported signatures: @@ -105,49 +112,56 @@ class PEAR_Exception extends Exception * PEAR_Exception(string $message, int $code); * PEAR_Exception(string $message, Exception $cause); * PEAR_Exception(string $message, Exception $cause, int $code); + * PEAR_Exception(string $message, array $causes); + * PEAR_Exception(string $message, array $causes, int $code); */ public function __construct($message, $p2 = null, $p3 = null) { - $code = null; - $cause = null; - if (is_int($p3) && $p2 instanceof Exception) { - $code = $p3; - $cause = $p2; - } elseif (is_int($p2)) { + if (is_int($p2)) { $code = $p2; - } elseif ($p2 instanceof Exception) { - $cause = $p2; + $this->cause = null; + } elseif ($p2 instanceof Exception || is_array($p2)) { + $code = $p3; + if (is_array($p2) && isset($p2['message'])) { + // fix potential problem of passing in a single warning + $p2 = array($p2); + } + $this->cause = $p2; + } else { + $code = null; + $this->cause = null; } - $this->cause = $cause; - $trace = parent::getTrace(); - $this->error_class = $trace[0]['class']; - $this->error_method = $trace[0]['function']; - $this->_method = $this->error_class . '::' . $this->error_method . '()'; parent::__construct($message, $code); - - $this->_signal(); + $this->signal(); } /** * @param mixed $callback - A valid php callback, see php func is_callable() - * - A PEAR_OBSERVER_* constant - * - An array(const PEAR_OBSERVER_*, mixed $options) - * - * @param string $label - The name of the observer. Use this if you want - * to remove it later with delObserver() + * - A PEAR_Exception::OBSERVER_* constant + * - An array(const PEAR_Exception::OBSERVER_*, + * mixed $options) + * @param string $label The name of the observer. Use this if you want + * to remove it later with removeObserver() */ - public static function addObserver($callback, $label = 'default') { self::$_observers[$label] = $callback; } - public static function delObserver($label = 'default') + public static function removeObserver($label = 'default') { unset(self::$_observers[$label]); } - private function _signal() + /** + * @return int unique identifier for an observer + */ + public static function getUniqueId() + { + return self::$_uniqueid++; + } + + private function signal() { foreach (self::$_observers as $func) { if (is_callable($func)) { @@ -156,15 +170,15 @@ class PEAR_Exception extends Exception } settype($func, 'array'); switch ($func[0]) { - case PEAR_OBSERVER_PRINT: + case self::OBSERVER_PRINT : $f = (isset($func[1])) ? $func[1] : '%s'; printf($f, $this->getMessage()); break; - case PEAR_OBSERVER_TRIGGER: + case self::OBSERVER_TRIGGER : $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; trigger_error($this->getMessage(), $f); break; - case PEAR_OBSERVER_DIE: + case self::OBSERVER_DIE : $f = (isset($func[1])) ? $func[1] : '%s'; die(printf($f, $this->getMessage())); break; @@ -174,48 +188,165 @@ class PEAR_Exception extends Exception } } - private function _getCauseMessage() + /** + * Return specific error information that can be used for more detailed + * error messages or translation. + * + * This method may be overridden in child exception classes in order + * to add functionality not present in PEAR_Exception and is a placeholder + * to define API + * + * The returned array must be an associative array of parameter => value like so: + *
+     * array('name' => $name, 'context' => array(...))
+     * 
+ * @return array + */ + public function getErrorData() { - $msg = " #{$this->_method} at {$this->file} ({$this->line})\n" . - " {$this->message}\n"; - if ($this->cause instanceof Exception) { - return $this->cause->_getCauseMessage() . $msg; - } - return $msg; + return array(); } /** - * @return Exception_object The context of the exception + * Returns the exception that caused this exception to be thrown + * @access public + * @return Exception|array The context of the exception */ public function getCause() { return $this->cause; } + /** + * Function must be public to call on caused exceptions + * @param array + */ + public function getCauseMessage(&$causes) + { + $trace = $this->getTraceSafe(); + $causes[] = array('class' => get_class($this), + 'message' => $this->message, + 'file' => $trace[0]['file'], + 'line' => $trace[0]['line']); + if ($this->cause instanceof PEAR_Exception) { + $this->cause->getCauseMessage($causes); + } + if (is_array($this->cause)) { + foreach ($this->cause as $cause) { + if ($cause instanceof PEAR_Exception) { + $cause->getCauseMessage($causes); + } elseif (is_array($cause) && isset($cause['message'])) { + // PEAR_ErrorStack warning + $causes[] = array( + 'class' => $cause['package'], + 'message' => $cause['message'], + 'file' => isset($cause['context']['file']) ? + $cause['context']['file'] : + 'unknown', + 'line' => isset($cause['context']['line']) ? + $cause['context']['line'] : + 'unknown', + ); + } + } + } + } + + public function getTraceSafe() + { + if (!isset($this->_trace)) { + $this->_trace = $this->getTrace(); + if (empty($this->_trace)) { + $backtrace = debug_backtrace(); + $this->_trace = array($backtrace[count($backtrace)-1]); + } + } + return $this->_trace; + } + public function getErrorClass() { - return $this->error_class; + $trace = $this->getTraceSafe(); + return $trace[0]['class']; } public function getErrorMethod() { - return $this->error_method; + $trace = $this->getTraceSafe(); + return $trace[0]['function']; } public function __toString() { - $str = get_class($this) . " occurred: \n" . - " Error message: {$this->message}\n" . - " Error code : {$this->code}\n" . - " File (Line) : {$this->file} ({$this->line})\n" . - " Method : {$this->_method}\n"; - if ($this->cause instanceof Exception) { - $str .= " Nested Error :\n" . $this->_getCauseMessage(); - } if (isset($_SERVER['REQUEST_URI'])) { - return nl2br('
'.htmlentities($str).'
'); + return $this->toHtml(); + } + return $this->toText(); + } + + public function toHtml() + { + $trace = $this->getTraceSafe(); + $causes = array(); + $this->getCauseMessage($causes); + $html = '' . "\n"; + foreach ($causes as $i => $cause) { + $html .= '\n"; + } + $html .= '' . "\n" + . '' + . '' + . '' . "\n"; + + foreach ($trace as $k => $v) { + $html .= '' + . '' + . '' . "\n"; + } + $html .= '' + . '' + . '' . "\n" + . '
' + . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' + . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' + . 'on line ' . $cause['line'] . '' + . "
Exception trace
#FunctionLocation
' . $k . ''; + if (!empty($v['class'])) { + $html .= $v['class'] . $v['type']; + } + $html .= $v['function']; + $args = array(); + if (!empty($v['args'])) { + foreach ($v['args'] as $arg) { + if (is_null($arg)) $args[] = 'null'; + elseif (is_array($arg)) $args[] = 'Array'; + elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; + elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; + elseif (is_int($arg) || is_double($arg)) $args[] = $arg; + else { + $arg = (string)$arg; + $str = htmlspecialchars(substr($arg, 0, 16)); + if (strlen($arg) > 16) $str .= '…'; + $args[] = "'" . $str . "'"; + } + } + } + $html .= '(' . implode(', ',$args) . ')' + . '' . $v['file'] . ':' . $v['line'] . '
' . ($k+1) . '{main} 
'; + return $html; + } + + public function toText() + { + $causes = array(); + $this->getCauseMessage($causes); + $causeMsg = ''; + foreach ($causes as $i => $cause) { + $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; } - return $str; + return $causeMsg . $this->getTraceAsString(); } } diff --git a/pear/PEAR/Installer.php b/pear/PEAR/Installer.php index 5b17826781..2dc91c5d97 100644 --- a/pear/PEAR/Installer.php +++ b/pear/PEAR/Installer.php @@ -165,7 +165,14 @@ class PEAR_Installer extends PEAR_Downloader include_once "OS/Guess.php"; $os = new OS_Guess(); } - if (!$os->matchSignature($atts['platform'])) { + if (strlen($atts['platform']) && $atts['platform']{0} == '!') { + $negate = true; + $platform = substr($atts['platform'], 1); + } else { + $negate = false; + $platform = $atts['platform']; + } + if ((bool) $os->matchSignature($platform) === $negate) { $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); return PEAR_INSTALLER_SKIPPED; } diff --git a/pear/PEAR/Registry.php b/pear/PEAR/Registry.php index f85bbfdd56..c3b21bbaf1 100644 --- a/pear/PEAR/Registry.php +++ b/pear/PEAR/Registry.php @@ -286,7 +286,9 @@ class PEAR_Registry extends PEAR $open_mode = 'r'; } - $this->lock_fp = @fopen($this->lockfile, $open_mode); + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } if (!is_resource($this->lock_fp)) { return $this->raiseError("could not create lock file" . @@ -312,6 +314,7 @@ class PEAR_Registry extends PEAR function _unlock() { $ret = $this->_lock(LOCK_UN); + fclose($this->lock_fp); $this->lock_fp = null; return $ret; }