From: Greg Beaver Date: Mon, 28 Mar 2005 16:46:06 +0000 (+0000) Subject: merge in PEAR 1.3.5 X-Git-Tag: php-5.0.4~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e1d1c8d9010d6b3184ba260d634df77dd5729996;p=php merge in PEAR 1.3.5 --- diff --git a/pear/OS/Guess.php b/pear/OS/Guess.php index 4b366d8c2a..f0566c1ec1 100644 --- a/pear/OS/Guess.php +++ b/pear/OS/Guess.php @@ -68,6 +68,11 @@ // SparcStation 20 Solaris 8: // SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20 // +// Mac OS X (Darwin) +// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh +// +// Mac OS X early versions +// // }}} @@ -97,11 +102,11 @@ class OS_Guess static $sysmap = array( 'HP-UX' => 'hpux', 'IRIX64' => 'irix', - // Darwin? ); static $cpumap = array( 'i586' => 'i386', 'i686' => 'i386', + 'ppc' => 'powerpc', ); if ($uname === null) { $uname = php_uname(); @@ -138,6 +143,24 @@ class OS_Guess // use only the first two digits from the kernel version $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]); break; + case 'Mac' : + $sysname = 'darwin'; + $nodename = $parts[2]; + $release = $parts[3]; + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + break; + case 'Darwin' : + if ($cpu == 'Macintosh') { + if ($parts[$n - 2] == 'Power') { + $cpu = 'powerpc'; + } + } + $release = ereg_replace('^([[:digit:]]+\.[[:digit:]]+).*', '\1', $parts[2]); + break; default: $release = ereg_replace('-.*', '', $parts[2]); break; @@ -255,7 +278,6 @@ class OS_Guess } } - /* * Local Variables: * indent-tabs-mode: nil diff --git a/pear/PEAR.php b/pear/PEAR.php index a42b825f6a..fa89ea56d4 100644 --- a/pear/PEAR.php +++ b/pear/PEAR.php @@ -59,7 +59,7 @@ $GLOBALS['_PEAR_destructor_object_list'] = array(); $GLOBALS['_PEAR_shutdown_funcs'] = array(); $GLOBALS['_PEAR_error_handler_stack'] = array(); -ini_set('track_errors', true); +@ini_set('track_errors', true); /** * Base class for other PEAR classes. Provides rudimentary @@ -152,7 +152,7 @@ class PEAR */ function PEAR($error_class = null) { - $classname = get_class($this); + $classname = strtolower(get_class($this)); if ($this->_debug) { print "PEAR constructor called, class=$classname\n"; } @@ -164,6 +164,10 @@ class PEAR if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = &$this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } break; } else { $classname = get_parent_class($classname); @@ -187,7 +191,7 @@ class PEAR */ function _PEAR() { if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", get_class($this)); + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); } } @@ -561,6 +565,77 @@ class PEAR } // }}} + function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + // {{{ pushErrorHandling() /** @@ -665,6 +740,9 @@ function _PEAR_call_destructors() sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); + if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } while (list($k, $objref) = each($_PEAR_destructor_object_list)) { $classname = get_class($objref); while ($classname) { @@ -738,7 +816,9 @@ class PEAR_Error $this->mode = $mode; $this->userinfo = $userinfo; if (function_exists("debug_backtrace")) { - $this->backtrace = debug_backtrace(); + if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { + $this->backtrace = debug_backtrace(); + } } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; @@ -929,14 +1009,16 @@ class PEAR_Error E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { - $callback = get_class($this->callback[0]) . '::' . + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } return sprintf('[%s: message="%s" code=%d mode=callback '. 'callback=%s prefix="%s" info="%s"]', - get_class($this), $this->message, $this->code, + strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo); } @@ -954,7 +1036,7 @@ class PEAR_Error } return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 'prefix="%s" info="%s"]', - get_class($this), $this->message, $this->code, + strtolower(get_class($this)), $this->message, $this->code, implode("|", $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo); @@ -963,8 +1045,6 @@ class PEAR_Error // }}} } -register_shutdown_function("_PEAR_call_destructors"); - /* * Local Variables: * mode: php diff --git a/pear/PEAR/Builder.php b/pear/PEAR/Builder.php index c6b4a4f248..0f37d24acb 100644 --- a/pear/PEAR/Builder.php +++ b/pear/PEAR/Builder.php @@ -150,6 +150,49 @@ class PEAR_Builder extends PEAR_Common } // }}} + // {{{ _harventInstDir + /** + * @param string + * @param string + * @param array + * @access private + */ + function _harvestInstDir($dest_prefix, $dirname, &$built_files) + { + $d = opendir($dirname); + if (!$d) + return false; + + $ret = true; + while (($ent = readdir($d)) !== false) { + if ($ent{0} == '.') + continue; + + $full = $dirname . DIRECTORY_SEPARATOR . $ent; + if (is_dir($full)) { + if (!$this->_harvestInstDir( + $dest_prefix . DIRECTORY_SEPARATOR . $ent, + $full, $built_files)) { + $ret = false; + break; + } + } else { + $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent; + $built_files[] = array( + 'file' => $full, + 'dest' => $dest, + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + } + } + closedir($d); + return $ret; + } + + // }}} + // {{{ build() /** @@ -231,14 +274,20 @@ class PEAR_Builder extends PEAR_Common } $build_basedir = "/var/tmp/pear-build-$user"; $build_dir = "$build_basedir/$info[package]-$info[version]"; + $inst_dir = "$build_basedir/install-$info[package]-$info[version]"; $this->log(1, "building in $build_dir"); if (is_dir($build_dir)) { - System::rm("-rf $build_dir"); + System::rm(array('-rf', $build_dir)); } - if (!System::mkDir("-p $build_dir")) { + if (!System::mkDir(array('-p', $build_dir))) { return $this->raiseError("could not create build dir: $build_dir"); } $this->addTempFile($build_dir); + if (!System::mkDir(array('-p', $inst_dir))) { + return $this->raiseError("could not create temporary install dir: $inst_dir"); + } + $this->addTempFile($inst_dir); + if (getenv('MAKE')) { $make_command = getenv('MAKE'); } else { @@ -247,10 +296,13 @@ class PEAR_Builder extends PEAR_Common $to_run = array( $configure_command, $make_command, + "$make_command INSTALL_ROOT=\"$inst_dir\" install", + "find \"$inst_dir\" -ls" ); if (!@chdir($build_dir)) { return $this->raiseError("could not chdir to $build_dir"); } + putenv('PHP_PEAR_VERSION=@PEAR-VER@'); foreach ($to_run as $cmd) { $err = $this->_runCommand($cmd, $callback); if (PEAR::isError($err)) { @@ -267,26 +319,8 @@ class PEAR_Builder extends PEAR_Common return $this->raiseError("no `modules' directory found"); } $built_files = array(); - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -3) == '.la') { - continue; - } - // harvest! - if (@copy("modules/$ent", "$dir/$ent")) { - $built_files[] = array( - 'file' => "$dir/$ent", - 'php_api' => $this->php_api_version, - 'zend_mod_api' => $this->zend_module_api_no, - 'zend_ext_api' => $this->zend_extension_api_no, - ); - - $this->log(1, "$ent copied to $dir/$ent"); - } else { - chdir($old_cwd); - return $this->raiseError("failed copying $ent to $dir"); - } - } - closedir($dp); + $prefix = exec("php-config --prefix"); + $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); chdir($old_cwd); return $built_files; } diff --git a/pear/PEAR/Command/Package.php b/pear/PEAR/Command/Package.php index d0aca3f8e5..0923a51775 100644 --- a/pear/PEAR/Command/Package.php +++ b/pear/PEAR/Command/Package.php @@ -15,6 +15,7 @@ // +----------------------------------------------------------------------+ // | Authors: Stig Bakken | // | Martin Jansen | +// | Greg Beaver | // +----------------------------------------------------------------------+ // // $Id$ @@ -159,7 +160,16 @@ use the "slide" option to move the release tag. 'recur' => array( 'shortopt' => 'r', 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', - ) + ), + 'ini' => array( + 'shortopt' => 'i', + 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', + 'arg' => 'SETTINGS' + ), + 'realtimelog' => array( + 'shortopt' => 'l', + 'doc' => 'Log test runs/results as they are run', + ), ), 'doc' => '[testfile|dir ...] Run regression tests with PHP\'s regression testing script (run-tests.php).', @@ -438,6 +448,7 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm { include_once 'PEAR/RunTest.php'; $log = new PEAR_Common; + $log->ui = &$this->ui; // slightly hacky, but it will work $run = new PEAR_RunTest($log); $tests = array(); if (isset($options['recur'])) { @@ -445,6 +456,9 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm } else { $depth = 1; } + if (!count($params)) { + $params[] = '.'; + } foreach ($params as $p) { if (is_dir($p)) { $dir = System::find(array($p, '-type', 'f', @@ -452,45 +466,99 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm '-name', '*.phpt')); $tests = array_merge($tests, $dir); } else { - $tests[] = $p; + if (!@file_exists($p)) { + if (!preg_match('/\.phpt$/', $p)) { + $p .= '.phpt'; + } + $dir = System::find(array(dirname($p), '-type', 'f', + '-maxdepth', $depth, + '-name', $p)); + $tests = array_merge($tests, $dir); + } else { + $tests[] = $p; + } } } + $ini_settings = ''; + if (isset($options['ini'])) { + $ini_settings .= $options['ini']; + } + if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { + $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; + } + if ($ini_settings) { + $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); + } + $skipped = $passed = $failed = array(); + $this->ui->outputData('Running ' . count($tests) . ' tests', $command); + $start = time(); + if (isset($options['realtimelog'])) { + @unlink('run-tests.log'); + } foreach ($tests as $t) { - $run->run($t); + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "Running test $t..."); + fclose($fp); + } + } + $result = $run->run($t, $ini_settings); + if (OS_WINDOWS) { + for($i=0;$i<2000;$i++) { + $i = $i; // delay - race conditions on windows + } + } + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "$result\n"); + fclose($fp); + } + } + if ($result == 'FAILED') { + $failed[] = $t; + } + if ($result == 'PASSED') { + $passed[] = $t; + } + if ($result == 'SKIPPED') { + $skipped[] = $t; + } } - - return true; - /* - $cwd = getcwd(); - $php = $this->config->get('php_bin'); - putenv("TEST_PHP_EXECUTABLE=$php"); - // all core PEAR tests use this constant to determine whether they should be run or not - putenv("PHP_PEAR_RUNTESTS=1"); - $ip = ini_get("include_path"); - $ps = OS_WINDOWS ? ';' : ':'; - $run_tests = $rtsts = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . 'run-tests.php'; - if (!file_exists($run_tests)) { - $run_tests = PEAR_INSTALL_DIR . DIRECTORY_SEPARATOR . 'run-tests.php'; - if (!file_exists($run_tests)) { - return $this->raiseError("No run-tests.php file found. Please copy this ". - "file from the sources of your PHP distribution to $rtsts"); + $total = date('i:s', time() - $start); + if (count($failed)) { + $output = "TOTAL TIME: $total\n"; + $output .= count($passed) . " PASSED TESTS\n"; + $output .= count($skipped) . " SKIPPED TESTS\n"; + $output .= count($failed) . " FAILED TESTS:\n"; + foreach ($failed as $failure) { + $output .= $failure . "\n"; + } + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + } else { + $fp = @fopen('run-tests.log', 'w'); } + if ($fp) { + fwrite($fp, $output, strlen($output)); + fclose($fp); + $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); + } + } elseif (@file_exists('run-tests.log') && !@is_dir('run-tests.log')) { + @unlink('run-tests.log'); } - if (OS_WINDOWS) { - // note, this requires a slightly modified version of run-tests.php - // for some setups - // unofficial download location is in the pear-dev archives - $argv = $params; - array_unshift($argv, $run_tests); - $argc = count($argv); - include $run_tests; - } else { - $plist = implode(' ', $params); - $cmd = "$php -d include_path=$cwd$ps$ip -f $run_tests -- $plist"; - system($cmd); + $this->ui->outputData('TOTAL TIME: ' . $total); + $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); + $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); + if (count($failed)) { + $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); + foreach ($failed as $failure) { + $this->ui->outputData($failure, $command); + } } + return true; - */ } // }}} diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index 3449ffaac3..cfb73c6031 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -69,7 +69,7 @@ $GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldli * Valid dependency relations * @var array */ -$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not'); +$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); /** * Valid file roles @@ -1129,18 +1129,31 @@ class PEAR_Common extends PEAR if (!empty($d['optional'])) { if (!in_array($d['optional'], array('yes', 'no'))) { $errors[] = "dependency $i: invalid relation optional attribute '$d[optional]', should be one of: yes no"; + } else { + if (($d['rel'] == 'not' || $d['rel'] == 'ne') && $d['optional'] == 'yes') { + $errors[] = "dependency $i: 'not' and 'ne' dependencies cannot be " . + "optional"; + } } } - if ($d['rel'] != 'has' && empty($d['version'])) { + if ($d['rel'] != 'not' && $d['rel'] != 'has' && empty($d['version'])) { $warnings[] = "dependency $i: missing version"; - } elseif ($d['rel'] == 'has' && !empty($d['version'])) { - $warnings[] = "dependency $i: version ignored for `has' dependencies"; + } elseif (($d['rel'] == 'not' || $d['rel'] == 'has') && !empty($d['version'])) { + $warnings[] = "dependency $i: version ignored for `$d[rel]' dependencies"; + } + if ($d['rel'] == 'not' && !empty($d['version'])) { + $warnings[] = "dependency $i: 'not' defines a total conflict, to exclude " . + "specific versions, use 'ne'"; } if ($d['type'] == 'php' && !empty($d['name'])) { $warnings[] = "dependency $i: name ignored for php type dependencies"; } elseif ($d['type'] != 'php' && empty($d['name'])) { $errors[] = "dependency $i: missing name"; } + if ($d['type'] == 'php' && $d['rel'] == 'not') { + $errors[] = "dependency $i: PHP dependencies cannot use 'not' " . + "rel, use 'ne' to exclude versions"; + } $i++; } } diff --git a/pear/PEAR/Dependency.php b/pear/PEAR/Dependency.php index 3239fc98ee..ec2bd7e86d 100644 --- a/pear/PEAR/Dependency.php +++ b/pear/PEAR/Dependency.php @@ -204,7 +204,7 @@ class PEAR_Dependency } foreach ($deps as $dep) { if ($dep['type'] == 'pkg' && strcasecmp($dep['name'], $package) == 0) { - if ($dep['rel'] == 'ne') { + if ($dep['rel'] == 'ne' || $dep['rel'] == 'not') { continue; } if (isset($dep['optional']) && $dep['optional'] == 'yes') { @@ -244,7 +244,7 @@ class PEAR_Dependency } if (!extension_loaded($name)) { - if ($relation == 'ne') { + if ($relation == 'not') { return false; } if ($opt) { @@ -322,7 +322,8 @@ class PEAR_Dependency return false; } if ($relation == 'not') { - $errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP"; + $errmsg = 'Invalid dependency - "not" is not allowed for php dependencies, ' . + 'php cannot conflict with itself'; return PEAR_DEPENDENCY_BAD_DEPENDENCY; } if (substr($req, 0, 2) == 'v.') { diff --git a/pear/PEAR/ErrorStack.php b/pear/PEAR/ErrorStack.php index 329e076a6e..d1dcf9233e 100644 --- a/pear/PEAR/ErrorStack.php +++ b/pear/PEAR/ErrorStack.php @@ -122,6 +122,10 @@ define('PEAR_ERRORSTACK_LOG', 3); * If this is returned, then the error is completely ignored. */ define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); /**#@-*/ /** @@ -308,7 +312,11 @@ class PEAR_ErrorStack { */ function setDefaultLogger(&$log) { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } } /** @@ -317,7 +325,11 @@ class PEAR_ErrorStack { */ function setLogger(&$log) { - $this->_logger = &$log; + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; + } } /** @@ -369,7 +381,7 @@ class PEAR_ErrorStack { } /** - * Set an error code => error message mapping callback + * Set a callback that generates context information (location of error) for an error stack * * This method sets the callback that can be used to generate context * information for an error. Passing in NULL will disable context generation @@ -446,10 +458,11 @@ class PEAR_ErrorStack { */ function staticPopCallback() { - array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); } + return $ret; } /** @@ -536,6 +549,7 @@ class PEAR_ErrorStack { $err['repackage'] = $repackage; } $push = $log = true; + $die = false; // try the overriding callback first $callback = $this->staticPopCallback(); if ($callback) { @@ -564,6 +578,9 @@ class PEAR_ErrorStack { case PEAR_ERRORSTACK_LOG: $push = false; break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; // anything else returned has the same effect as pushandlog } } @@ -576,6 +593,9 @@ class PEAR_ErrorStack { $this->_log($err); } } + if ($die) { + die(); + } if ($this->_compat && $push) { return $this->raiseError($msg, $code, null, null, $err); } @@ -626,7 +646,15 @@ class PEAR_ErrorStack { * @param array $levels Error level => Log constant map * @access protected */ - function _log($err, $levels = array( + function _log($err) + { + if ($this->_logger) { + $logger = &$this->_logger; + } else { + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( 'exception' => PEAR_LOG_CRIT, 'alert' => PEAR_LOG_ALERT, 'critical' => PEAR_LOG_CRIT, @@ -634,17 +662,15 @@ class PEAR_ErrorStack { 'warning' => PEAR_LOG_WARNING, 'notice' => PEAR_LOG_NOTICE, 'info' => PEAR_LOG_INFO, - 'debug' => PEAR_LOG_DEBUG)) - { - if (isset($levels[$err['level']])) { - $level = $levels[$err['level']]; - } else { - $level = PEAR_LOG_INFO; - } - if ($this->_logger) { - $this->_logger->log($err['message'], $level, $err); - } else { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']->log($err['message'], $level, $err); + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; + } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); } } @@ -749,7 +775,8 @@ class PEAR_ErrorStack { * @static * @return array */ - function staticGetErrors($purge = false, $level = false, $merge = false, $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) + function staticGetErrors($purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) { $ret = array(); if (!is_callable($sortfunc)) { diff --git a/pear/PEAR/Exception.php b/pear/PEAR/Exception.php index a5be021a97..1e191f84ea 100644 --- a/pear/PEAR/Exception.php +++ b/pear/PEAR/Exception.php @@ -224,10 +224,16 @@ class PEAR_Exception extends Exception public function getCauseMessage(&$causes) { $trace = $this->getTraceSafe(); - $causes[] = array('class' => get_class($this), - 'message' => $this->message, - 'file' => $trace[0]['file'], - 'line' => $trace[0]['line']); + $cause = array('class' => get_class($this), + 'message' => $this->message, + 'file' => 'unknown', + 'line' => 'unknown'); + if (isset($trace[0])) { + if (isset($trace[0]['file'])) { + $cause['file'] = $trace[0]['file']; + $cause['line'] = $trace[0]['line']; + } + } if ($this->cause instanceof PEAR_Exception) { $this->cause->getCauseMessage($causes); } diff --git a/pear/PEAR/Installer.php b/pear/PEAR/Installer.php index 2dc91c5d97..af4ae5b62e 100644 --- a/pear/PEAR/Installer.php +++ b/pear/PEAR/Installer.php @@ -797,28 +797,43 @@ class PEAR_Installer extends PEAR_Downloader $this->log(1, "\nBuild process completed successfully"); foreach ($built as $ext) { $bn = basename($ext['file']); - list($_ext_name, ) = explode('.', $bn); - if (extension_loaded($_ext_name)) { - $this->raiseError("Extension '$_ext_name' already loaded. Please unload it ". - "in your php.ini file prior to install or upgrade it."); - } - // extension dir must be created if it doesn't exist - // patch by Tomas Cox (modified by Greg Beaver) - $ext_dir = $this->config->get('ext_dir'); - if (!@is_dir($ext_dir) && !System::mkdir(array('-p', $ext_dir))) { - $this->log(3, "+ mkdir -p $ext_dir"); - return $this->raiseError("failed to create extension dir '$ext_dir'"); + list($_ext_name, $_ext_suff) = explode('.', $bn); + if ($_ext_suff == '.so' || $_ext_suff == '.dll') { + if (extension_loaded($_ext_name)) { + $this->raiseError("Extension '$_ext_name' already loaded. " . + 'Please unload it in your php.ini file ' . + 'prior to install or upgrade'); + } + $role = 'ext'; + } else { + $role = 'src'; } - $dest = $ext_dir . DIRECTORY_SEPARATOR . $bn; - $this->log(1, "Installing '$bn' at ext_dir ($dest)"); - $this->log(3, "+ cp $ext[file] ext_dir ($dest)"); + $dest = $ext['dest']; + $this->log(1, "Installing '$ext[file]'"); $copyto = $this->_prependPath($dest, $this->installroot); + $copydir = dirname($copyto); + if (!@is_dir($copydir)) { + if (!$this->mkDirHier($copydir)) { + return $this->raiseError("failed to mkdir $copydir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $copydir"); + } if (!@copy($ext['file'], $copyto)) { - $this->rollbackFileTransaction(); - return $this->raiseError("failed to copy $bn to $copyto"); + return $this->raiseError("failed to write $copyto", PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ cp $ext[file] $copyto"); + if (!OS_WINDOWS) { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + $this->addFileOperation('chmod', array($mode, $copyto)); + if (!@chmod($copyto, $mode)) { + $this->log(0, "failed to change mode of $copyto"); + } } + $this->addFileOperation('rename', array($ext['file'], $copyto)); + $pkginfo['filelist'][$bn] = array( - 'role' => 'ext', + 'role' => $role, 'installed_as' => $dest, 'php_api' => $ext['php_api'], 'zend_mod_api' => $ext['zend_mod_api'], diff --git a/pear/PEAR/Registry.php b/pear/PEAR/Registry.php index c3b21bbaf1..631328bea9 100644 --- a/pear/PEAR/Registry.php +++ b/pear/PEAR/Registry.php @@ -314,7 +314,9 @@ class PEAR_Registry extends PEAR function _unlock() { $ret = $this->_lock(LOCK_UN); - fclose($this->lock_fp); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); + } $this->lock_fp = null; return $ret; } diff --git a/pear/package-PEAR.xml b/pear/package-PEAR.xml index 26b64cdaf4..6aa1690033 100644 --- a/pear/package-PEAR.xml +++ b/pear/package-PEAR.xml @@ -48,26 +48,15 @@ - 1.3.3 - 2004-10-28 + 1.3.5 + 2005-02-18 stable PHP License -Installer: - * fix Bug #1186 raise a notice error on PEAR::Common $_packageName - * fix Bug #1249 display the right state when using --force option - * fix Bug #2189 upgrade-all stops if dependancy fails - * fix Bug #1637 The use of interface causes warnings when packaging with PEAR - * fix Bug #1420 Parser bug for T_DOUBLE_COLON - * fix Request #2220 pear5 build fails on dual php4/php5 system - * fix Bug #1163 pear makerpm fails with packages that supply role="doc" - -Other: - * add PEAR_Exception class for PHP5 users - * fix critical problem in package.xml for linux in 1.3.2 - * fix staticPopCallback() in PEAR_ErrorStack - * fix warning in PEAR_Registry for windows 98 users - + * fix Bug #3505: pecl can't install PDO + * enhance pear run-tests dramatically + * fix Bug #3506: pear install should export the pear version into the environment + @@ -98,11 +87,14 @@ Other: - + + + + @@ -160,22 +152,49 @@ PEAR_ErrorStack: - 1.3 - 2004-02-20 + 1.3.3 + 2004-10-28 stable -PEAR Installer: - -* Bug #171 --alldeps with a rel="eq" should install the required version, if possible -* Bug #249 installing from an url doesnt work -* Bug #248 --force command does not work as expected -* Bug #293 [Patch] PEAR_Error not calling static method callbacks for error-handler -* Bug #324 pear -G gives Fatal Error (PHP-GTK not installed, but error is at engine level) -* Bug #594 PEAR_Common::analyzeSourceCode fails on string with $var and { -* Bug #521 Incorrect filename in naming warnings -* Moved download code into its own class -* Fully unit tested the installer, packager, downloader, and PEAR_Common +Installer: + * fix Bug #1186 raise a notice error on PEAR::Common $_packageName + * fix Bug #1249 display the right state when using --force option + * fix Bug #2189 upgrade-all stops if dependancy fails + * fix Bug #1637 The use of interface causes warnings when packaging with PEAR + * fix Bug #1420 Parser bug for T_DOUBLE_COLON + * fix Request #2220 pear5 build fails on dual php4/php5 system + * fix Bug #1163 pear makerpm fails with packages that supply role="doc" +Other: + * add PEAR_Exception class for PHP5 users + * fix critical problem in package.xml for linux in 1.3.2 + * fix staticPopCallback() in PEAR_ErrorStack + * fix warning in PEAR_Registry for windows 98 users + + + + 1.3.3.1 + 2004-11-08 + stable + + add RunTest.php to package.xml, make run-tests display failed tests, and use ui + + + + 1.3.4 + 2005-01-01 + stable + + * fix a serious problem caused by a bug in all versions of PHP that caused multiple registration + of the shutdown function of PEAR.php + * fix Bug #2861: package.dtd does not define NUMBER + * fix Bug #2946: ini_set warning errors + * fix Bug #3026: Dependency type "ne" is needed, "not" is not handled + properly + * fix Bug #3061: potential warnings in PEAR_Exception + * implement Request #2848: PEAR_ErrorStack logger extends, PEAR_ERRORSTACK_DIE + * implement Request #2914: Dynamic Include Path for run-tests command + * make pear help listing more useful (put how-to-use info at the bottom of the listing) diff --git a/pear/package.dtd b/pear/package.dtd index 45beb7ba84..5ed7a7e9a1 100644 --- a/pear/package.dtd +++ b/pear/package.dtd @@ -1,5 +1,5 @@ - + @@ -65,8 +65,8 @@ outputData('WARNING: running in safe mode requires that all files created ' . + 'be the same uid as the current script. PHP reports this script is uid: ' . + @getmyuid() . ', and current user is: ' . @get_current_user()); +} $pear_user_config = ''; $pear_system_config = ''; @@ -212,9 +217,6 @@ function usage($error = null, $helpsubject = null) $put = cmdHelp($helpsubject); } else { $put = - "Usage: $progname [options] command [command-options] \n". - "Type \"$progname help options\" to list all options.\n". - "Type \"$progname help \" to get the help for the specified command.\n". "Commands:\n"; $maxlen = max(array_map("strlen", $all_commands)); $formatstr = "%-{$maxlen}s %s\n"; @@ -222,6 +224,11 @@ function usage($error = null, $helpsubject = null) foreach ($all_commands as $cmd => $class) { $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd)); } + $put .= + "Usage: $progname [options] command [command-options] \n". + "Type \"$progname help options\" to list all options.\n". + "Type \"$progname help shortcuts\" to list all command shortcuts.\n". + "Type \"$progname help \" to get the help for the specified command."; } fputs($stderr, "$put\n"); fclose($stderr); diff --git a/pear/template.spec b/pear/template.spec index 9bf356c7f5..f6f91a524e 100644 --- a/pear/template.spec +++ b/pear/template.spec @@ -30,25 +30,29 @@ pear -v -c %{buildroot}/pearrc \ %build echo BuildRoot=%{buildroot} +%clean +[ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot} + %postun pear uninstall --nodeps -r @package@ -rm @rpm_xml_dir@/@package@.xml %post pear install --nodeps -r @rpm_xml_dir@/@package@.xml %install -pear -c %{buildroot}/pearrc install --nodeps -R %{buildroot} \ - $RPM_SOURCE_DIR/@package@-%{version}.tgz +pear -c "%{buildroot}/pearrc" install --nodeps -R "%{buildroot}" \ + "$RPM_SOURCE_DIR/@package@-%{version}.tgz" rm %{buildroot}/pearrc rm %{buildroot}/%{_libdir}/php/pear/.filemap rm %{buildroot}/%{_libdir}/php/pear/.lock rm -rf %{buildroot}/%{_libdir}/php/pear/.registry -if [ -d "%{buildroot}/docs/@package@/doc" ]; then - rm -rf $RPM_BUILD_DIR/doc - mv %{buildroot}/docs/@package@/doc $RPM_BUILD_DIR - rm -rf %{buildroot}/docs -fi +for DOCDIR in docs doc examples; do + if [ -d "%{buildroot}/docs/@package@/$DOCDIR" ]; then + rm -rf $RPM_BUILD_DIR/$DOCDIR + mv %{buildroot}/docs/@package@/$DOCDIR $RPM_BUILD_DIR + rm -rf %{buildroot}/docs + fi +done mkdir -p %{buildroot}@rpm_xml_dir@ tar -xzf $RPM_SOURCE_DIR/@package@-%{version}.tgz package.xml cp -p package.xml %{buildroot}@rpm_xml_dir@/@package@.xml