]> granicus.if.org Git - php/commitdiff
merge in PEAR 1.3.5
authorGreg Beaver <cellog@php.net>
Mon, 28 Mar 2005 16:46:06 +0000 (16:46 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 28 Mar 2005 16:46:06 +0000 (16:46 +0000)
14 files changed:
pear/OS/Guess.php
pear/PEAR.php
pear/PEAR/Builder.php
pear/PEAR/Command/Package.php
pear/PEAR/Common.php
pear/PEAR/Dependency.php
pear/PEAR/ErrorStack.php
pear/PEAR/Exception.php
pear/PEAR/Installer.php
pear/PEAR/Registry.php
pear/package-PEAR.xml
pear/package.dtd
pear/scripts/pearcmd.php
pear/template.spec

index 4b366d8c2ae8aeab0794146907954efd45ba31f0..f0566c1ec103251f76fad4b2f396f3575cff2c85 100644 (file)
 // 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
index a42b825f6a5c20b6726c84d34f962483f4fd2f7d..fa89ea56d4f952d65398e03deef3abd823d80342 100644 (file)
@@ -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
index c6b4a4f248a6c8caff550e3d4b4b9da545ea47d6..0f37d24acb02fbae27dfab017a64630843d4353d 100644 (file)
@@ -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;
     }
index d0aca3f8e56370323c3ccb599bda419a2bf8e5c5..0923a517755520e4574d34a8a816ed5a4cf29f63 100644 (file)
@@ -15,6 +15,7 @@
 // +----------------------------------------------------------------------+
 // | Authors: Stig Bakken <ssb@php.net>                                   |
 // |          Martin Jansen <mj@php.net>                                  |
+// |          Greg Beaver <cellog@php.net>                                |
 // +----------------------------------------------------------------------+
 //
 // $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;
-        */
     }
 
     // }}}
index 3449ffaac3042c2c2622f091d1dc0d6f08c51fd6..cfb73c6031864d5f461d938ec8e8d00a1db9feaa 100644 (file)
@@ -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++;
             }
         }
index 3239fc98ee34a24f28f82149caeaef67f0ac42eb..ec2bd7e86d833e86736d35285a3bf75366b54486 100644 (file)
@@ -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.') {
index 329e076a6e91894aa05d340ca6bbb78e4200fa70..d1dcf9233eb74e77d553da6e61beb2efe645ad88 100644 (file)
@@ -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)) {
index a5be021a974e1b837853538730a3ffd2930f7661..1e191f84ea5d6a6853c6e3e687a57d781cee14c1 100644 (file)
@@ -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);
         }
index 2dc91c5d9755ba5a8c028c0af2e3fefd7af67cdd..af4ae5b62e68f1b8d57325fcd94da04f62deba41 100644 (file)
@@ -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'],
index c3b21bbaf13da02abd525d2bfa2ef3ce90400d61..631328bea9ded13ce3cda441ae3bb91da5b296eb 100644 (file)
@@ -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;
     }
index 26b64cdaf4bba9792230d73161f6e761e7bd342b..6aa169003300260cce26d67c371dfc25da5aad9f 100644 (file)
     </maintainer>
   </maintainers>
   <release>
-    <version>1.3.3</version>
-    <date>2004-10-28</date>
+    <version>1.3.5</version>
+    <date>2005-02-18</date>
     <state>stable</state>
     <license>PHP License</license>
     <notes>
-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
-</notes>
+ * 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
+    </notes>
     <provides type="class" name="OS_Guess" />
     <provides type="class" name="System" />
     <provides type="function" name="md5_file" />
@@ -98,11 +87,14 @@ Other:
         <file role="php" name="Downloader.php"/>
         <file role="php" name="Exception.php"/>
         <file role="php" name="ErrorStack.php"/>
-        <file role="php" name="Builder.php"/>
+        <file role="php" name="Builder.php">
+         <replace from="@PEAR-VER@" to="version" type="package-info"/>
+        </file>
         <file role="php" name="Installer.php"/>
         <file role="php" name="Packager.php"/>
         <file role="php" name="Registry.php"/>
         <file role="php" name="Remote.php"/>
+        <file role="php" name="RunTest.php"/>
       </dir>
       <dir name="scripts" baseinstalldir="/">
         <file role="script" install-as="pear" name="pear.sh">
@@ -160,22 +152,49 @@ PEAR_ErrorStack:
     </notes>
   </release>
   <release>
-    <version>1.3</version>
-    <date>2004-02-20</date>
+    <version>1.3.3</version>
+    <date>2004-10-28</date>
     <state>stable</state>
     <notes>
-PEAR Installer:
-
-* Bug #171 --alldeps with a rel=&quot;eq&quot; 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
+    </notes>
+   </release>
+  <release>
+    <version>1.3.3.1</version>
+    <date>2004-11-08</date>
+    <state>stable</state>
+    <notes>
+     add RunTest.php to package.xml, make run-tests display failed tests, and use ui
+    </notes>
+   </release>
+  <release>
+    <version>1.3.4</version>
+    <date>2005-01-01</date>
+    <state>stable</state>
+    <notes>
+ * 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 &quot;ne&quot; is needed, &quot;not&quot; 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)
     </notes>
    </release>
   </changelog>
index 45beb7ba849feb13350c9d05f08acd7e8fd00135..5ed7a7e9a1a8de7300491df291d2bb786836e8c8 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-     $Id: package.dtd,v 1.35 2004-01-25 23:36:28 pajoye Exp $
+     $Id: package.dtd,v 1.35.4.1 2005-03-28 16:46:06 cellog Exp $
 
      This is the PEAR package description, version 1.0.
      It should be used with the informal public identifier:
@@ -20,7 +20,7 @@
          Stig S. Bakken <ssb@php.net>
 
   -->
-
+<!ENTITY % NUMBER "CDATA">
 <!ELEMENT package (name|summary|description|license|maintainers|release|changelog)+>
 <!ATTLIST package type    (source|binary|empty) "empty"
                   version CDATA                 #REQUIRED>
@@ -65,8 +65,8 @@
 <!ATTLIST file role           (php|ext|src|test|doc|data|script) 'php'
                debug          (na|on|off)        'na'
                zts            (na|on|off)        'na'
-               phpapi         NUMBER             #IMPLIED
-               zendapi        NUMBER             #IMPLIED
+               phpapi         %NUMBER;           #IMPLIED
+               zendapi        %NUMBER;           #IMPLIED
                format         CDATA              #IMPLIED
                baseinstalldir CDATA              #IMPLIED
                platform       CDATA              #IMPLIED
index b7d10e5e12370804d113b4918040bee65a6167b2..ff9366142ef78357111304973a6b1e31044276e1 100644 (file)
@@ -29,7 +29,7 @@ if ('@include_path@' != '@'.'include_path'.'@') {
 }
 ini_set('allow_url_fopen', true);
 if (!ini_get('safe_mode')) {
-    set_time_limit(0);
+    @set_time_limit(0);
 }
 ob_implicit_flush(true);
 ini_set('track_errors', true);
@@ -75,6 +75,11 @@ if ($progname == 'gpear' || $progname == 'pear-gtk') {
 PEAR_Command::setFrontendType($fetype);
 $ui = &PEAR_Command::getFrontendObject();
 PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
+if (ini_get('safe_mode')) {
+    $ui->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] <parameters>\n".
-            "Type \"$progname help options\" to list all options.\n".
-            "Type \"$progname help <command>\" 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] <parameters>\n".
+            "Type \"$progname help options\" to list all options.\n".
+            "Type \"$progname help shortcuts\" to list all command shortcuts.\n".
+            "Type \"$progname help <command>\" to get the help for the specified command.";
     }
     fputs($stderr, "$put\n");
     fclose($stderr);
index 9bf356c7f5a62cf5b527c09e768108fb80a4a29e..f6f91a524ec7cabad4c072736f2cd8576490c1ce 100644 (file)
@@ -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