]> granicus.if.org Git - php/commitdiff
- Bring phar command into sync with 5_3 and PECL
authorSteph Fox <sfox@php.net>
Fri, 1 Aug 2008 13:41:30 +0000 (13:41 +0000)
committerSteph Fox <sfox@php.net>
Fri, 1 Aug 2008 13:41:30 +0000 (13:41 +0000)
ext/phar/phar/clicommand.inc
ext/phar/phar/directorygraphiterator.inc
ext/phar/phar/directorytreeiterator.inc
ext/phar/phar/invertedregexiterator.inc
ext/phar/phar/phar.inc
ext/phar/phar/phar.php
ext/phar/phar/pharcommand.inc

index 067456d691b5a64967a23e150dbd957ffdf43f7b..79bf5c8855c523a36a20bbf9669fb52a811a0c3f 100755 (executable)
@@ -4,7 +4,7 @@
  * @ingroup Phar
  * @brief class CLICommand
  * @author  Marcus Boerger
- * @date    2007 - 2007
+ * @date    2007 - 2008
  *
  * Phar Command
  */
  */
 abstract class CLICommand
 {
-    protected $argc;
-    protected $argv;
-    protected $cmds = array();
-    protected $args = array();
-    protected $typs = array();
-
-    function __construct($argc, array $argv)
-    {
-        $this->argc = $argc;
-        $this->argv = $argv;
-        $this->cmds = self::getCommands($this);
-        $this->typs = self::getArgTyps($this);
-
-        if ($argc < 2) {
-            self::error("No command given, check ${argv[0]} help\n");
-        } elseif (!isset($this->cmds[$argv[1]]['run'])) {
-            self::error("Unknown command '${argv[1]}', check ${argv[0]} help\n");
-        } else {
-            $command = $argv[1];
-        }
-
-        if (isset($this->cmds[$command]['arg'])) {
-            $this->args = call_user_func(array($this, $this->cmds[$command]['arg']));
-            $i = 1;
-            $missing = false;
-            while (++$i < $argc) {
-                if ($argv[$i][0] == '-') {
-                    if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]])) {
-                        $arg = $argv[$i][1];
-                        if (++$i >= $argc) {
-                            self::error("Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n");
-                        } else {
-                            $this->args[$arg]['val'] = $this->checkArgTyp($arg, $i, $argc, $argv);
-                        }
-                    }  else {
-                        self::error("Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n");
-                    }
-                } else {
-                    break;
-                }
-            }
-            if (isset($this->args[''])) {
-                if ($i >= $argc) {
-                    if (isset($this->args['']['require']) && $this->args['']['require']) {
-                        self::error("Missing default trailing arguments to command $command, check ${argv[0]} help\n");
-                    }
-                } else {
-                    $this->args['']['val'] = array();
-                    while($i < $argc) {
-                        $this->args['']['val'][] = $argv[$i++];
-                    }
-                }
-            } else if ($i < $argc) {
-                self::error("Unexpected default arguments to command $command, check ${argv[0]} help\n");
-            }
-            
-            foreach($this->args as $arg => $inf) {
-                if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required']) {
-                    $missing .=  "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
-                }
-            }
-            if (strlen($missing))
-            {
-                self::error($missing);
-            }
-        }
-
-        call_user_func(array($this, $this->cmds[$command]['run']), $this->args);
-    }
-
-    static function notice ($msg)
-    {
-        fprintf(STDERR, $msg);
-    }
-
-    static function error ($msg, $exit_code = 1) 
-    {
-        self::notice($msg);
-        exit($exit_code);
-    }
-
-    function checkArgTyp($arg, $i, $argc, $argv)
-    {
-        $typ = $this->args[$arg]['typ'];
-
-        if (isset($this->typs[$typ]['typ'])) {
-            return call_user_func(array($this, $this->typs[$typ]['typ']), $argv[$i], $this->args[$arg], $arg);
-        } else {
-            return $argv[$i];
-        }
-    }
-
-    static function getSubFuncs(CLICommand $cmdclass, $prefix, array $subs)
-    {
-        $a = array();
-        $r = new ReflectionClass($cmdclass);
-        $l = strlen($prefix);
-
-        foreach($r->getMethods() as $m)
-        {
-            if (substr($m->name, 0, $l) == $prefix)
-            {
-                foreach($subs as $sub)
-                {
-                    $what = substr($m->name, $l+strlen($sub)+1);
-                    $func = $prefix . $sub . '_' . $what;
-                    $what = str_replace('_', '-', $what);
-                    if ($r->hasMethod($func))
-                    {
-                        if (!isset($a[$what]))
-                        {
-                            $a[$what] = array();
-                        }
-                        $a[$what][$sub] = /*$m->class . '::' .*/ $func;
-                    }
-                }
-            }
-        }
-        return $a;
-    }
-
-    static function getCommands(CLICommand $cmdclass)
-    {
-        return self::getSubFuncs($cmdclass, 'cli_cmd_', array('arg','inf','run'));
-    }
-
-    static function getArgTyps(CLICommand $cmdclass)
-    {
-        return self::getSubFuncs($cmdclass, 'cli_arg_', array('typ'));
-    }
-
-    static function cli_arg_typ_bool($arg, $cfg, $key)
-    {
-        return (bool)$arg;
-    }
-
-    
-    static function cli_arg_typ_int($arg, $cfg, $key) 
-    {
-        if ((int)$arg != $arg) {
-            self::error("Argument to -$key must be an integer.\n");
-        }
-
-        return (int)$arg;
-    }
-    
-    static function cli_arg_typ_regex($arg, $cfg, $key)
-    {
-        if (strlen($arg))
-        {
-            if (strlen($arg) > 1 && $arg[0] == $arg[strlen($arg)-1] && strpos('/,', $arg) !== false)
-            {
-                return $arg;
-            }
-            else
-            {
-                return '/' . $arg . '/';
-            }
-        }
-        else
-        {
-            return NULL;
-        }
-    }
-
-    static function cli_arg_typ_select($arg, $cfg, $key)
-    {
-        if (!in_array($arg, array_keys($cfg['select']))) {
-            self::error("Parameter value '$arg' not one of '" . join("', '", array_keys($cfg['select'])) . "'.\n");
-        }
-        return $arg;
-    }
-
-    static function cli_arg_typ_dir($arg, $cfg, $key)
-    {
-        $f = realpath($arg);
-
-        if ($f===false || !file_exists($f) || !is_dir($f)) {
-            self::error("Requested path '$arg' does not exist.\n");
-        }
-        return $f;
-    }
-
-    static function cli_arg_typ_file($arg)
-    {
-        $f = new SplFileInfo($arg);
-        $f = $f->getRealPath();
-        if ($f===false || !file_exists($f))
-        {
-            echo "Requested file '$arg' does not exist.\n";
-            exit(1);
-        }
-        return $f;
-    }
-
-    static function cli_arg_typ_filenew($arg, $cfg, $key)
-    {
-        $d = dirname($arg);
-        $f = realpath($d);
-        
-        if ($f === false) {
-            self::error("Path for file '$arg' does not exist.\n");
-        }
-        return $f . '/' . basename($arg);
-    }
-
-    static function cli_arg_typ_filecont($arg, $cfg, $key)
-    {
-        return file_get_contents(self::cli_arg_typ_file($arg, $cfg, $key));
-    }
-
-    function cli_get_SP2($l1, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 8);
-    }
-
-    function cli_get_SP3($l1, $l2, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 8 + 2 + $l2 + 2);
-    }
-
-    static function cli_cmd_inf_help()
-    {
-        return "This help or help for a selected command.";
-    }
-
-    private function cli_wordwrap($what, $l, $sp)
-    {
-        $p = max(79 - $l, 40);     // minimum length for paragraph
-        $b = substr($what, 0, $l); // strip out initial $l
-        $r = substr($what, $l);    // remainder
-        $r = str_replace("\n", "\n".$sp, $r); // in remainder replace \n's
-        return $b . wordwrap($r, $p, "\n".$sp);
-    }
-
-    private function cli_help_get_args($func, $l, $sp, $required)
-    {
-        $inf = "";
-        foreach(call_user_func($func, $l, $sp) as $arg => $conf)
-        {
-            if ((isset($conf['required']) && $conf['required']) != $required)
-            {
-                continue;
-            }
-            if (strlen($arg))
-            {
-                $arg = "-$arg  ";
-            }
-            else
-            {
-                $arg = "... ";
-            }
-            $sp2 = $this->cli_get_SP2($l, $inf);
-            $l2  = strlen($sp2);
-            $inf .= $this->cli_wordwrap($sp . $arg . $conf['inf'], $l2, $sp2) . "\n";
-            if (isset($conf['select']) && count($conf['select']))
-            {
-                $ls = 0;
-                foreach($conf['select'] as $opt => $what)
-                {
-                    $ls = max($ls, strlen($opt));
-                }
-                $sp3 = $this->cli_get_SP3($l, $ls, $inf);
-                $l3  = strlen($sp3);
-                foreach($conf['select'] as $opt => $what)
-                {
-                    $inf .= $this->cli_wordwrap($sp2 . "  " . sprintf("%-${ls}s  ", $opt) . $what, $l3, $sp3) . "\n";
-                }
-            }
-        }
-        if (strlen($inf))
-        {
-            if ($required)
-            {
-                return $sp . "Required arguments:\n\n" . $inf;
-            }
-            else
-            {
-                return $sp . "Optional arguments:\n\n". $inf;
-            }
-        }
-    }
-
-    function cli_cmd_arg_help()
-    {
-        return array('' => array('typ'=>'any','val'=>NULL,'inf'=>'Optional command to retrieve help for.'));
-    }
-
-    function cli_cmd_run_help()
-    {
-        $argv  = $this->argv;
-        $which = $this->args['']['val'];
-        if (isset($which))
-        {
-            if (count($which) != 1) {
-                self::error("More than one command given.\n");
-            }
-            
-            $which = $which[0];
-            if (!array_key_exists($which, $this->cmds)) {
-                self::error("Unknown command, cannot retrieve help.\n");
-            }
-
-            $l = strlen($which);
-            $cmds = array($which => $this->cmds[$which]);
-        } else {
-            echo "\n$argv[0] <command> [options]\n\n";
-            $l = 0;
-            ksort($this->cmds);
-            foreach($this->cmds as $name => $funcs) {
-                $l = max($l, strlen($name));
-            }
-            $inf = "Commands:";
-            $lst = "";
-            $ind = strlen($inf) + 1;
-            foreach($this->cmds as $name => $funcs)
-            {
-                $lst .= ' ' . $name;
-            }
-            echo $this->cli_wordwrap($inf.$lst, $ind, str_repeat(' ', $ind)) . "\n\n";
-            $cmds = $this->cmds;
-        }
-        $sp = str_repeat(' ', $l + 2);
-        foreach($cmds as $name => $funcs)
-        {
-            $inf = $name . substr($sp, strlen($name));
-            if (isset($funcs['inf']))
-            {
-                $inf .= $this->cli_wordwrap(call_user_func(array($this, $funcs['inf'])), $l, $sp) . "\n";
-                if (isset($funcs['arg']))
-                {
-                    $inf .= "\n";
-                    $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, true);
-                    $inf .= "\n";
-                    $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, false);
-                }
-            }
-            echo "$inf\n\n";
-        }
-        exit(0);
-    }
-
-    static function cli_cmd_inf_help_list()
-    {
-        return "Lists available commands.";
-    }
-
-    function cli_cmd_run_help_list()
-    {
-        ksort($this->cmds);
-        $lst = '';
-        foreach($this->cmds as $name => $funcs) {
-            $lst .= $name . ' ';
-        }
-        echo substr($lst, 0, -1) . "\n";
-    }
+       protected $argc;
+       protected $argv;
+       protected $cmds = array();
+       protected $args = array();
+       protected $typs = array();
+
+       function __construct($argc, array $argv)
+       {
+               $this->argc = $argc;
+               $this->argv = $argv;
+               $this->cmds = self::getCommands($this);
+               $this->typs = self::getArgTyps($this);
+
+               if ($argc < 2) {
+                       self::error("No command given, check ${argv[0]} help\n");
+               } elseif (!isset($this->cmds[$argv[1]]['run'])) {
+                       self::error("Unknown command '${argv[1]}', check ${argv[0]} help\n");
+               } else {
+                       $command = $argv[1];
+               }
+
+               if (isset($this->cmds[$command]['arg'])) {
+                       $this->args = call_user_func(array($this, $this->cmds[$command]['arg']));
+                       $i = 1;
+                       $missing = false;
+                       while (++$i < $argc) {
+                               if ($argv[$i][0] == '-') {
+                                       if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]])) {
+                                               $arg = $argv[$i][1];
+                                               if (++$i >= $argc) {
+                                                       self::error("Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n");
+                                               } else {
+                                                       $this->args[$arg]['val'] = $this->checkArgTyp($arg, $i, $argc, $argv);
+                                               }
+                                       }  else {
+                                               self::error("Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n");
+                                       }
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       if (isset($this->args[''])) {
+                               if ($i >= $argc) {
+                                       if (isset($this->args['']['require']) && $this->args['']['require']) {
+                                               self::error("Missing default trailing arguments to command $command, check ${argv[0]} help\n");
+                                       }
+                               } else {
+                                       $this->args['']['val'] = array();
+                                       while($i < $argc) {
+                                               $this->args['']['val'][] = $argv[$i++];
+                                       }
+                               }
+                       } else if ($i < $argc) {
+                               self::error("Unexpected default arguments to command $command, check ${argv[0]} help\n");
+                       }
+
+                       foreach($this->args as $arg => $inf) {
+                               if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required']) {
+                                       $missing .=  "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
+                               }
+                       }
+
+                       if (strlen($missing)) {
+                               self::error($missing);
+                       }
+               }
+
+               call_user_func(array($this, $this->cmds[$command]['run']), $this->args);
+       }
+
+       static function notice ($msg)
+       {
+               fprintf(STDERR, $msg);
+       }
+
+       static function error ($msg, $exit_code = 1)
+       {
+               self::notice($msg);
+               exit($exit_code);
+       }
+
+       function checkArgTyp($arg, $i, $argc, $argv)
+       {
+               $typ = $this->args[$arg]['typ'];
+
+               if (isset($this->typs[$typ]['typ'])) {
+                       return call_user_func(array($this, $this->typs[$typ]['typ']), $argv[$i], $this->args[$arg], $arg);
+               } else {
+                       return $argv[$i];
+               }
+       }
+
+       static function getSubFuncs(CLICommand $cmdclass, $prefix, array $subs)
+       {
+               $a = array();
+               $r = new ReflectionClass($cmdclass);
+               $l = strlen($prefix);
+
+               foreach($r->getMethods() as $m) {
+                       if (substr($m->name, 0, $l) == $prefix) {
+                               foreach($subs as $sub) {
+                                       $what = substr($m->name, $l+strlen($sub)+1);
+                                       $func = $prefix . $sub . '_' . $what;
+                                       $what = str_replace('_', '-', $what);
+                                       if ($r->hasMethod($func)) {
+                                               if (!isset($a[$what])) {
+                                                       $a[$what] = array();
+                                               }
+                                               $a[$what][$sub] = /*$m->class . '::' .*/ $func;
+                                       }
+                               }
+                       }
+               }
+               return $a;
+       }
+
+       static function getCommands(CLICommand $cmdclass)
+       {
+               return self::getSubFuncs($cmdclass, 'cli_cmd_', array('arg','inf','run'));
+       }
+
+       static function getArgTyps(CLICommand $cmdclass)
+       {
+               return self::getSubFuncs($cmdclass, 'cli_arg_', array('typ'));
+       }
+
+       static function cli_arg_typ_bool($arg, $cfg, $key)
+       {
+               return (bool)$arg;
+       }
+
+       static function cli_arg_typ_int($arg, $cfg, $key)
+       {
+               if ((int)$arg != $arg) {
+                       self::error("Argument to -$key must be an integer.\n");
+               }
+
+               return (int)$arg;
+       }
+
+       static function cli_arg_typ_regex($arg, $cfg, $key)
+       {
+               if (strlen($arg)) {
+                       if (strlen($arg) > 1 && $arg[0] == $arg[strlen($arg)-1] && strpos('/,', $arg) !== false) {
+                               return $arg;
+                       } else {
+                               return '/' . $arg . '/';
+                       }
+               } else {
+                       return NULL;
+               }
+       }
+
+       static function cli_arg_typ_select($arg, $cfg, $key)
+       {
+               if (!in_array($arg, array_keys($cfg['select']))) {
+                       self::error("Parameter value '$arg' not one of '" . join("', '", array_keys($cfg['select'])) . "'.\n");
+               }
+               return $arg;
+       }
+
+       static function cli_arg_typ_dir($arg, $cfg, $key)
+       {
+               $f = realpath($arg);
+
+               if ($f===false || !file_exists($f) || !is_dir($f)) {
+                       self::error("Requested path '$arg' does not exist.\n");
+               }
+               return $f;
+       }
+
+       static function cli_arg_typ_file($arg)
+       {
+               $f = new SplFileInfo($arg);
+               $f = $f->getRealPath();
+               if ($f===false || !file_exists($f)) {
+                       echo "Requested file '$arg' does not exist.\n";
+                       exit(1);
+               }
+               return $f;
+       }
+
+       static function cli_arg_typ_filenew($arg, $cfg, $key)
+       {
+               $d = dirname($arg);
+               $f = realpath($d);
+
+               if ($f === false) {
+                       self::error("Path for file '$arg' does not exist.\n");
+               }
+               return $f . '/' . basename($arg);
+       }
+
+       static function cli_arg_typ_filecont($arg, $cfg, $key)
+       {
+               return file_get_contents(self::cli_arg_typ_file($arg, $cfg, $key));
+       }
+
+       function cli_get_SP2($l1, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 4 + 8);
+       }
+
+       function cli_get_SP3($l1, $l2, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 4 + 8 + 2 + $l2 + 2);
+       }
+
+       static function cli_cmd_inf_help()
+       {
+               return "This help or help for a selected command.";
+       }
+
+       private function cli_wordwrap($what, $l, $sp)
+       {
+               $p = max(79 - $l, 40);     // minimum length for paragraph
+               $b = substr($what, 0, $l); // strip out initial $l
+               $r = substr($what, $l);    // remainder
+               $r = str_replace("\n", "\n".$sp, $r); // in remainder replace \n's
+               return $b . wordwrap($r, $p, "\n".$sp);
+       }
+
+       private function cli_help_get_args($func, $l, $sp, $required)
+       {
+               $inf = "";
+               foreach(call_user_func($func, $l, $sp) as $arg => $conf) {
+                       if ((isset($conf['required']) && $conf['required']) != $required) {
+                               continue;
+                       }
+
+                       if (strlen($arg)) {
+                               $arg = "-$arg  ";
+                       } else {
+                               $arg = "... ";
+                       }
+
+                       $sp2 = $this->cli_get_SP2($l, $inf);
+                       $l2  = strlen($sp2);
+                       $inf .= $this->cli_wordwrap($sp . $arg . $conf['inf'], $l2, $sp2) . "\n";
+
+                       if (isset($conf['select']) && count($conf['select'])) {
+                               $ls = 0;
+                               foreach($conf['select'] as $opt => $what) {
+                                       $ls = max($ls, strlen($opt));
+                               }
+                               $sp3 = $this->cli_get_SP3($l, $ls, $inf);
+                               $l3  = strlen($sp3);
+                               foreach($conf['select'] as $opt => $what) {
+                                       $inf .= $this->cli_wordwrap($sp2 . "  " . sprintf("%-${ls}s  ", $opt) . $what, $l3, $sp3) . "\n";
+                               }
+                       }
+               }
+               if (strlen($inf)) {
+                       if ($required) {
+                               return $sp . "Required arguments:\n\n" . $inf;
+                       } else {
+                               return $sp . "Optional arguments:\n\n". $inf;
+                       }
+               }
+       }
+
+       function cli_cmd_arg_help()
+       {
+               return array('' => array('typ'=>'any','val'=>NULL,'inf'=>'Optional command to retrieve help for.'));
+       }
+
+       function cli_cmd_run_help()
+       {
+               $argv  = $this->argv;
+               $which = $this->args['']['val'];
+               if (isset($which)) {
+                       if (count($which) != 1) {
+                               self::error("More than one command given.\n");
+                       }
+
+                       $which = $which[0];
+                       if (!array_key_exists($which, $this->cmds)) {
+                               if (strtolower($which) == 'commands') {
+                                       self::cli_cmd_run_help_list();
+                                       exit(0);
+                               }
+                               self::error("Unknown command, cannot retrieve help.\n");
+                       }
+
+                       $l = strlen($which);
+                       $cmds = array($which => $this->cmds[$which]);
+               } else {
+                       echo "\n$argv[0] <command> [options]\n\n";
+                       $l = 0;
+                       ksort($this->cmds);
+                       foreach($this->cmds as $name => $funcs) {
+                               $l = max($l, strlen($name));
+                       }
+                       $inf = "Commands:";
+                       $lst = "";
+                       $ind = strlen($inf) + 1;
+                       foreach($this->cmds as $name => $funcs) {
+                               $lst .= ' ' . $name;
+                       }
+                       echo $this->cli_wordwrap($inf.$lst, $ind, str_repeat(' ', $ind)) . "\n\n";
+                       $cmds = $this->cmds;
+               }
+               $sp = str_repeat(' ', $l + 2);
+               foreach($cmds as $name => $funcs) {
+                       $inf = $name . substr($sp, strlen($name));
+                       if (isset($funcs['inf'])) {
+                               $inf .= $this->cli_wordwrap(call_user_func(array($this, $funcs['inf'])), $l, $sp) . "\n";
+                               if (isset($funcs['arg'])) {
+                                       $inf .= "\n";
+                                       $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, true);
+                                       $inf .= "\n";
+                                       $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, false);
+                               }
+                       }
+                       echo "$inf\n\n";
+               }
+               exit(0);
+       }
+
+       static function cli_cmd_inf_help_list()
+       {
+               return "Lists available commands.";
+       }
+
+       function cli_cmd_run_help_list()
+       {
+               ksort($this->cmds);
+               echo join(' ', array_keys($this->cmds)) . "\n";
+       }
 }
 
 ?>
index 5808e3b89ea15c665b32c93b849ffc1aa549e66c..5a658ddabcef5c3d046a5497a45814f91a8a6961 100755 (executable)
@@ -4,7 +4,7 @@
  * @ingroup Examples
  * @brief class DirectoryGraphIterator
  * @author  Marcus Boerger
- * @date    2003 - 2005
+ * @date    2003 - 2008
  *
  * SPL - Standard PHP Library
  */
@@ -23,9 +23,9 @@ class DirectoryGraphIterator extends DirectoryTreeIterator
                                new ParentIterator(
                                        new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
                                        )
-                               ), 
+                               ),
                                CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
-                       ), 
+                       ),
                        parent::SELF_FIRST
                );
        }
index 8e65d0db120eb6ca2c7e5319c7288b2e229d4924..9ed2e1a1bf57db3522e675e0590e50f8e03068cc 100755 (executable)
@@ -4,7 +4,7 @@
  * @ingroup Examples
  * @brief class DirectoryTreeIterator
  * @author  Marcus Boerger
- * @date    2003 - 2005
+ * @date    2003 - 2008
  *
  * SPL - Standard PHP Library
  */
@@ -24,27 +24,27 @@ class DirectoryTreeIterator extends RecursiveIteratorIterator
                parent::__construct(
                        new RecursiveCachingIterator(
                                new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
-                               ), 
+                               ),
                                CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
-                       ), 
+                       ),
                        parent::SELF_FIRST
                );
        }
 
        /** @return the current element prefixed with ASCII graphics
-        */     
+        */
        function current()
        {
                $tree = '';
                for ($l=0; $l < $this->getDepth(); $l++) {
                        $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : '  ';
                }
-               return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') 
-                      . $this->getSubIterator($l)->__toString();
+               return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-')
+                                        . $this->getSubIterator($l)->__toString();
        }
 
        /** Aggregates the inner iterator
-        */     
+        */
        function __call($func, $params)
        {
                return call_user_func_array(array($this->getSubIterator(), $func), $params);
index 7eea533a220be1feb9dc30e90a9e90aede8e5091..aec87e6ab14a0af612e7a62a77b11c5b0aa57e24 100755 (executable)
@@ -4,7 +4,7 @@
  * @ingroup Phar
  * @brief class InvertedRegexIterator
  * @author  Marcus Boerger
- * @date    2007 - 2007
+ * @date    2007 - 2008
  *
  * Inverted RegexIterator
  */
@@ -17,7 +17,7 @@
 class InvertedRegexIterator extends RegexIterator
 {
        /** @return !RegexIterator::accept()
-        */     
+        */
        function accept()
        {
                return !RegexIterator::accept();
index a7c6f6d5fe5f64ebc8ea0d3c6511c2b7992f3202..7e7d61851eba5043c6adb6341a959b2aa509b076 100755 (executable)
@@ -5,7 +5,7 @@
  * @ingroup Phar
  * @brief class Phar
  * @author  Marcus Boerger
- * @date    2007 - 2007
+ * @date    2007 - 2008
  *
  * Phar Command
  */
index 68a437b20649cdf024aae6e218392a83339f381f..f6f26c23f28cd601011db09cb7154e704b9925f0 100755 (executable)
@@ -5,47 +5,44 @@
  * @ingroup Phar
  * @brief class CLICommand
  * @author  Marcus Boerger
- * @date    2007 - 2007
+ * @date    2007 - 2008
  *
  * Phar Command
  */
 
 if (!extension_loaded('phar'))
 {
-       if (!class_exists('PHP_Archive', 0))
-       {
-           echo "Neither Extension Phar nor class PHP_Archive are available.\n";
-       exit(1);
-    }
-    if (!in_array('phar', stream_get_wrappers()))
-    {
-           stream_wrapper_register('phar', 'PHP_Archive');
-    }
-    if (!class_exists('Phar',0)) {
-           require 'phar://'.__FILE__.'/phar.inc';
-    }
+       if (!class_exists('PHP_Archive', 0)) {
+               echo "Neither Extension Phar nor class PHP_Archive are available.\n";
+               exit(1);
+       }
+       if (!in_array('phar', stream_get_wrappers())) {
+               stream_wrapper_register('phar', 'PHP_Archive');
+       }
+       if (!class_exists('Phar',0)) {
+               require 'phar://'.__FILE__.'/phar.inc';
+       }
 }
 
 foreach(array("SPL", "Reflection") as $ext)
 {
-    if (!extension_loaded($ext))
-    {
-        echo "$argv[0] requires PHP extension $ext.\n";
-        exit(1);
-    }
+       if (!extension_loaded($ext)) {
+               echo "$argv[0] requires PHP extension $ext.\n";
+               exit(1);
+       }
 }
 
 function command_include($file)
 {
-    $file = 'phar://' . __FILE__ . '/' . $file;
-    if (file_exists($file)) {
-        include($file);
-    }
+       $file = 'phar://' . __FILE__ . '/' . $file;
+       if (file_exists($file)) {
+               include($file);
+       }
 }
 
 function command_autoload($classname)
 {
-    command_include(strtolower($classname) . '.inc');
+       command_include(strtolower($classname) . '.inc');
 }
 
 Phar::mapPhar();
@@ -54,4 +51,6 @@ spl_autoload_register('command_autoload');
 
 new PharCommand($argc, $argv);
 
-__HALT_COMPILER(); ?>
\ No newline at end of file
+__HALT_COMPILER();
+
+?>
\ No newline at end of file
index e95f138d86c56875f0a5e147f6476e14656ebb14..80b6f18d076d3e770b62248b956b6e87fa4c97aa 100755 (executable)
@@ -5,7 +5,7 @@
  * @ingroup Phar
  * @brief class CLICommand
  * @author  Marcus Boerger
- * @date    2007 - 2007
+ * @date    2007 - 2008
  *
  * Phar Command
  */
  */
 class PharCommand extends CLICommand
 {
-    // {{{ public function cli_get_SP2
-    public function cli_get_SP2($l1, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 9);
-    }
-    // }}}
-    // {{{ public function cli_get_SP3
-    /**
-     * Cli Get SP3
-     *
-     * @param string $l1      Eleven
-     * @param string $l2      Twelve
-     * @param string $arg_inf 
-     * @return string  The repeated string.
-     */
-    function cli_get_SP3($l1, $l2, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
-    }
-    // }}}
-    // {{{ static function phar_args
-    /**
-     * Phar arguments
-     * 
-     * This function contains all the phar commands
-     *
-     * @param  string $which    Which argument is chosen.
-     * @param  string $phartype The type of phar, specific file to work on
-     * @return unknown
-     */
-    static function phar_args($which, $phartype)
-    {
-        $phar_args = array(
-            'a' => array(
-                'typ' => 'alias',
-                'val' => NULL,
-                'inf' => '<alias>  Provide an alias name for the phar file.'
-            ),
-            'b' => array(
-                'typ' => 'any',
-                'val' => NULL,
-                'inf' => '<bang>   Hash-bang line to start the archive (e.g. #!/usr/bin/php). The hash '
-                         .'         mark itself \'#!\' and the newline character are optional.'
-            ),
-            'c' => array(
-                'typ' => 'compalg',
-                'val' => NULL,
-                'inf' => '<algo>   Compression algorithm.',
-                'select' => array(
-                    '0'    => 'No compression',
-                    'none' => 'No compression',
-                    'auto' => 'Automatically select compression algorithm'
-                )
-            ),
-            'e' => array(
-                'typ' => 'entry',
-                'val' => NULL,
-                'inf' => '<entry>  Name of entry to work on (must include PHAR internal directory name if any).'
-            ),
-            'f' => array(
-                'typ' => $phartype,
-                'val' => NULL,
-                'inf' => '<file>   Specifies the phar file to work on.'
-            ),
-            'h' => array(
-                'typ' => 'select',
-                'val' => NULL,
-                'inf' => '<method> Selects the hash algorithmn.',
-                'select' => array('md5' => 'MD5','sha1' => 'SHA1')
-            ),
-            'i' => array(
-                'typ' => 'regex',
-                'val' => NULL,
-                'inf' => '<regex>  Specifies a regular expression for input files.'
-            ),
-            'k' => array(
-                'typ' => 'any',
-                'val' => NULL,
-                'inf' => '<index>  Subscription index to work on.',
-            ),
-            'l' => array(
-                'typ' => 'int',
-                'val' => 0,
-                'inf' => '<level>  Number of preceeding subdirectories to strip from file entries',
-            ),
-            'm' => array(
-                'typ' => 'any',
-                'val' => NULL,
-                'inf' => '<meta>   Meta data to store with entry (serialized php data).'
-            ),
-            'p' => array(
-                'typ' => 'loader',
-                'val' => NULL,
-                'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
-                         .'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
-                         .'pear command. When using \'0\' the command does not error out when the '
-                         .'class file cannot be located. This switch also adds some code around the '
-                         .'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
-                         .'if necessary. And finally this switch will add the file phar.inc from '
-                         .'this package and load it to ensure class Phar is present.'
-                         ,
-            ),
-            's' => array(
-                'typ' => 'file',
-                'val' => NULL,
-                'inf' => '<stub>   Select the stub file.'
-            ),
-            'x' => array(
-                'typ' => 'regex',
-                'val' => NULL,
-                'inf' => '<regex>  Regular expression for input files to exclude.'
-            ),
-
-        );
-
-        if (extension_loaded('zlib')) {
-            $phar_args['c']['select']['gz']    = 'GZip compression';
-            $phar_args['c']['select']['gzip']  = 'GZip compression';
-        }
-
-        if (extension_loaded('bz2')) {
-            $phar_args['c']['select']['bz2']   = 'BZip2 compression';
-            $phar_args['c']['select']['bzip2'] = 'BZip2 compression';
-        }
-
-        $hash_avail = Phar::getSupportedSignatures();
-        if (in_array('SHA-256', $hash_avail)) {
-            $phar_args['h']['select']['sha256'] = 'SHA256';
-        }
-
-        if (in_array('SHA-512', Phar::getSupportedSignatures())) {
-            $phar_args['h']['select']['sha512'] = 'SHA512';
-        }
-
-        $args = array();
-
-        foreach($phar_args as $lkey => $cfg) {
-            $ukey     = strtoupper($lkey);
-            $required = strpos($which, $ukey) !== false;
-            $optional = strpos($which, $lkey) !== false;
-
-            if ($required || $optional) {
-                $args[$lkey] = $cfg;
-                $args[$lkey]['required'] = $required;
-            }
-        }
-        return $args;
-    }
-    // }}}
-    // {{{ static function strEndsWith
-    /**
-     * String Ends With
-     * 
-     * Wether a string end with another needle.
-     *
-     * @param string $haystack  The haystack
-     * @param string $needle    The needle.
-     * @return mixed false if doesn't end with anything, the string 
-     *               substr'ed if the string ends with the needle.
-     */
-    static function strEndsWith($haystack, $needle)
-    {
-        return substr($haystack, -strlen($needle)) == $needle;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_loader
-    /**
-     * Argument type loader
-     *
-     * @param string $arg   Either 'auto', 'optional' or an filename that 
-     *                      contains class PHP_Archive
-     * @param  string $cfg  Configuration to pass to a new file
-     * @param  string $key  The key 
-     * @return string $arg  The argument.
-     */
-    static function cli_arg_typ_loader($arg, $cfg, $key)
-    {
-        if (($arg == '0' || $arg == '1') && !file_exists($arg)) {
-            $found = NULL;
-            foreach(split("\n", `pear list-files PHP_Archive`) as $ent) {
-                $matches = NULL;
-                if (preg_match(",^php[ \t]+([^ \t].*pear[\\\\/]PHP[\\\\/]Archive.php)$,", $ent, $matches)) {
-                    $found = $matches[1];
-                    break;
-                }
-            }
-            if (!isset($found)) {
-                $msg = "Pear package PHP_Archive or Archive.php class file not found.\n";
-                if ($arg == '0') {
-                    self::notice($msg);
-                } else {
-                    self::error($msg);
-                }
-            }
-            $arg = $found;
-        }
-        return self::cli_arg_typ_file($arg);
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharnew
-    /**
-     * Argument type new phar
-     *
-     * @param  string $arg  The new phar component.
-     * @param  string $cfg  Configuration to pass to a new file
-     * @param  string $key  The key 
-     * @return string $arg  The new argument file.
-     */
-    static function cli_arg_typ_pharnew($arg, $cfg, $key)
-    {
-        $arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
-        if (!Phar::isValidPharFilename($arg)) {
-            self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or '.phar.gz'.\n");
-        }
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharfile
-    /**
-     * Argument type existing Phar file
-     * 
-     * Return filenam eof an existing Phar.
-     *
-     * @param  string $arg      The file in the phar to open.
-     * @param  string $cfg      The configuration information
-     * @param  string $key      The key information.
-     * @return string $pharfile The name of the loaded Phar file.
-     * @note The Phar will be loaded
-     */
-    static function cli_arg_typ_pharfile($arg, $cfg, $key)
-    {
-        try {
-            $pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
-
-            if (!Phar::loadPhar($pharfile)) {
-                self::error("Unable to open phar '$arg'\n");
-            }
-
-            return $pharfile;
-        } catch(Exception $e) {
-            self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharurl
-    /**
-     * Argument type Phar url-like
-     * 
-     * Check the argument as cli_arg_Typ_phar and return its name prefixed 
-     * with phar://
-     * 
-     * Ex:
-     * <code>
-     *  $arg = 'pharchive.phar/file.php';
-     *  cli_arg_typ_pharurl($arg)
-     * </code>
-     *
-     * @param  string $arg The url-like phar archive to retrieve.
-     * @return string The phar file-archive.
-     */
-    static function cli_arg_typ_pharurl($arg, $cfg, $key)
-    {
-        return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_phar
-    /**
-     * Cli argument type phar
-     *
-     * @param  string $arg  The phar archive to use.
-     * @return object new Phar of the passed argument.
-     */
-    static function cli_arg_typ_phar($arg, $cfg, $key)
-    {
-        try {
-            return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
-        } catch(Exception $e) {
-            self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_entry
-    /**
-     * Argument type Entry name
-     *
-     * @param  string $arg The argument (the entry)
-     * @return string $arg The entry itself.
-     */
-    static function cli_arg_typ_entry($arg, $cfg, $key)
-    {
-        // no further check atm, maybe check for no '/' at beginning
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_compalg
-    /**
-     * Argument type compression algorithm
-     *
-     * @param  string $arg  The phar selection
-     * @param  string $cfg  The config option.
-     * @param  string $key  The key information.
-     * @return string $arg  The selected algorithm
-     */
-    static function cli_arg_typ_compalg($arg, $cfg, $key)
-    {
-        $arg = self::cli_arg_typ_select($arg, $cfg, $key);
-        
-        switch($arg) {
-            case 'auto':
-                if (extension_loaded('zlib')) {
-                    $arg = 'gz';
-                } elseif (extension_loaded('bz2')) {
-                    $arg = 'bz2';
-                } else {
-                    $arg = '0';
-                }
-                break;
-        }
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_pack
-    /**
-     * Information pack
-     *
-     * @return string A description about packing files into a Phar archive.
-     */
-    static function cli_cmd_inf_pack()
-    {
-        return "Pack files into a PHAR archive.\n" .  
-               "When using -s <stub>, then the stub file is being " .
-               "excluded from the list of input files/dirs." .
-               "To create an archive that contains PEAR class PHP_Archiave " .
-               "then point -p argument to PHP/Archive.php.\n";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_pack
-    /**
-     * Pack a new phar infos
-     *
-     * @return array  $args  The arguments for a new Phar archive.
-     */
-    static function cli_cmd_arg_pack()
-    {
-        $args = self::phar_args('abcFhilpsx', 'pharnew');
-        
-        $args[''] = array(
-            'typ'     => 'any',     
-            'val'      => NULL,      
-            'required' => 1, 
-            'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
-            
-        );
-        
-        return $args;
-    }
-    // }}}
-    // {{{ function phar_set_stub_begin
-    /**
-     * Set the stub
-     */
-    public function phar_set_stub_begin(Phar $phar, $stub, $loader = NULL, $hashbang = NULL)
-    {
-        if (isset($stub)) {
-            $c = file_get_contents($stub);
-
-            if (substr($c, 0, 2) == '#!') {
-                if (strpos($c, "\n") !== false) {
-                    if (!isset($hashbang)) {
-                        $hashbang = substr($c, 0, strpos($c, "\n") + 1);
-                    }
-                    $c = substr($c, strpos($c, "\n") + 1);
-                } else {
-                    if (!isset($hashbang)) {
-                        $hashbang = $c;
-                    }
-                    $c = NULL;
-                }
-            }
-
-            if (isset($hashbang)) {
-                if (substr($hashbang, 0, 2) != '#!') {
-                    $hashbang = '#!' . $hashbang;
-                }
-                if (substr($hashbang, -1) != "\n") {
-                    $hashbang .= "\n";
-                }
-            } else {
-               $hashbang = "";
-            }
-
-            if (isset($loader)) {
-                $s = "<?php if (!class_exists('PHP_Archive')) {\n?>";
-                $s .= file_get_contents($loader);
-                $s .= "<?php\n";
-                $s .= "}\n";
-                $s .= "if (!in_array('phar', stream_get_wrappers())) {\n";
-                $s .= "\tstream_wrapper_register('phar', 'PHP_Archive');\n";
-                $s .= "}\n";
-                $s .= "if (!class_exists('Phar',0)) {\n";
-                $s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
-                $s .= "}\n";
-                $s .= '?>';
-                $s .= $c;
-
-                $phar->setStub($hashbang . $s);
-            } else {
-                $phar->setStub($hashbang . $c);
-            }
-            return new SplFileInfo($stub);
-        }
-        return NULL;
-    }
-    // }}}
-    // {{{ function phar_set_stub_end
-    /**
-     * Set stub end
-     */
-    public function phar_set_stub_end(Phar $phar, $stub, $loader = NULL)
-    {
-        if (isset($stub) && isset($loader)) {
-            if (substr(__FILE__, -15) == 'pharcommand.inc') {
-                self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
-            } else {
-                self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
-            }
-        }
-    }
-    // }}}
-    // {{{ function cli_cmd_run_pack
-    /**
-     * Pack a new Phar
-     * 
-     * This function will try to pack a new Phar archive.
-     * 
-     * @see Exit to make sure that we are done.
-     */
-    public function cli_cmd_run_pack()
-    {
-        if (ini_get('phar.readonly')) {
-            self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
-        }
-        
-        if (!Phar::canWrite()) {
-            self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
-        }
-
-        $alias    = $this->args['a']['val'];
-        $hashbang = $this->args['b']['val'];
-        $archive  = $this->args['f']['val'];
-        $hash     = $this->args['h']['val'];
-        $regex    = $this->args['i']['val'];
-        $level    = $this->args['l']['val'];
-        $loader   = $this->args['p']['val'];
-        $stub     = $this->args['s']['val'];
-        $invregex = $this->args['x']['val'];
-        $input    = $this->args['']['val'];
-
-        $phar  = new Phar($archive, 0, $alias);
-
-        $phar->startBuffering();
-
-        $stub = $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
-
-        if (!is_array($input)) {
-            $this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
-        } else {
-            foreach($input as $i) {
-                $this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
-            }
-        }
-
-        $this->phar_set_stub_end($phar, $stub, $loader);
-
-        switch($this->args['c']['val']) {
-            case 'gz':
-            case 'gzip':
-                $phar->compressAllFilesGZ();
-                break;
-            case 'bz2':
-            case 'bzip2':
-                $phar->compressAllFilesBZIP2();
-                break;
-            default:
-                $phar->uncompressAllFiles();
-                break;
-        }
-
-        if ($hash) {
-            $phar->setSignatureAlgorithm($hash);
-        }
-
-        $phar->stopBuffering();
-        exit(0);
-    }
-    // }}}
-    // {{{ static function phar_add
-    /**
-     * Add files to a phar archive.
-     *
-     * This function will take a directory and iterate through
-     * it and get the files to insert into the Phar archive.
-     * 
-     * @param Phar        $phar      The phar object.
-     * @param string      $input     The input directory
-     * @param string      $regex     The regex use in RegexIterator.
-     * @param string      $invregex  The InvertedRegexIterator expression.
-     * @param SplFileInfo $stub Stub file object    
-     * @param mixed       $compress  Compression algorithm or NULL
-     * @param boolean     $noloader  Whether to prevent adding the loader
-     */
-    static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
-    {
-        if ($input && is_file($input) && !is_dir($input)) {
-            return self::phar_add_file($phar, $level, $input, $input, $compress);
-        }
-        $dir   = new RecursiveDirectoryIterator($input);
-        $dir   = new RecursiveIteratorIterator($dir);
-
-        if (isset($regex)) {
-            $dir = new RegexIterator($dir, $regex);
-        }
-
-        if (isset($invregex)) {
-            $dir = new InvertedRegexIterator($dir, $invregex);
-        }
-
-        try {
-            foreach($dir as $file) {
-                if (empty($stub) || $file->getRealPath() != $stub->getRealPath()) {
-                    self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
-                }
-            }
-        } catch(Excpetion $e) {
-            self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function phar_add_file
-    /**
-     * Add a phar file
-     *
-     * This function adds a file to a phar archive.
-     *
-     * @param Phar    $phar      The phar object
-     * @param string  $level     The level of the file.
-     * @param string  $entry     The entry point
-     * @param string  $file      The file to add to the archive
-     * @param string  $compress  The compression scheme for the file.
-     * @param boolean $noloader  Whether to prevent adding the loader
-     */
-    static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
-    {
-        $entry = str_replace('//', '/', $entry);
-        while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
-            $entry = substr($entry, $p+1);
-        }
-
-    if ($noloader && $entry == 'phar.inc') {
-        return;
-    }
-
-        echo "$entry\n";
-
-        $phar[$entry] = file_get_contents($file);
-        switch($compress) {
-            case 'gz':
-            case 'gzip':
-                $phar[$entry]->setCompressedGZ();
-                break;
-            case 'bz2':
-            case 'bzip2':
-                $phar[$entry]->setCompressedBZIP2();
-                break;
-            default:
-                break;
-        }
-    }
-    // }}}
-    // {{{ public function phar_dir_echo
-    /**
-     * Echo directory
-     *
-     * @param string $pn      
-     * @param unknown_type $f
-     */
-    public function phar_dir_echo($pn, $f)
-    {
-        echo "$f\n";
-    }
-    // }}}
-    // {{{ public function phar_dir_operation
-    /**
-     * Directory operations
-     * 
-     * Phar directory operations.
-     *
-     * @param RecursiveIteratorIterator $dir  The recursiveIteratorIterator object.
-     * @param string                    $func Function to call on the iterations
-     * @param array                     $args Function arguments.
-     */
-    public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
-    {
-        $regex   = $this->args['i']['val'];
-        $invregex= $this->args['x']['val'];
-
-        if (isset($regex)) {
-            $dir = new RegexIterator($dir, $regex);
-        }
-
-        if (isset($invregex)) {
-            $dir = new InvertedRegexIterator($dir, $invregex);
-        }
-
-        $any = false;
-        foreach($dir as $pn => $f) {
-            $any = true;
-            call_user_func($func, $pn, $f, $args);
-        }
-        return $any;
-    }
-    // {{{ static function cli_cmd_inf_list
-    /**
-     * Cli Command Info List
-     *
-     * @return string What inf does
-     */
-    static function cli_cmd_inf_list()
-    {
-        return "List contents of a PHAR archive.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_list
-    /**
-     * Cli Command Argument List
-     *
-     * @return arguments list
-     */
-    static function cli_cmd_arg_list()
-    {
-        return self::phar_args('Fix', 'pharurl');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_list
-    /**
-     * Cli Command Run List
-     *
-     * @see $this->phar_dir_operation
-     */
-    public function cli_cmd_run_list()
-    {
-        $this->phar_dir_operation(
-            new DirectoryTreeIterator(
-                $this->args['f']['val']), 
-                array($this, 'phar_dir_echo')
-            );
-    }
-    // }}}
-    // {{{ static function cli_command_inf_tree
-    /**
-     * Cli Command Inf Tree
-     *
-     * @return string  The description of a directory tree for a Phar archive.
-     */
-    static function cli_cmd_inf_tree()
-    {
-        return "Get a directory tree for a PHAR archive.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_tree
-    /**
-     * Cli Command Argument Tree
-     *
-     * @return string Arguments in URL format.
-     */
-    static function cli_cmd_arg_tree()
-    {
-        return self::phar_args('Fix', 'pharurl');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_tree
-    /**
-     * Cli Command Run Tree
-     * 
-     * Set the phar_dir_operation with a directorygraphiterator.
-     * 
-     * @see DirectoryGraphIterator
-     * @see $this->phar_dir_operation
-     *
-     */
-    public function cli_cmd_run_tree()
-    {
-        $a = $this->phar_dir_operation(
-            new DirectoryGraphIterator(
-                $this->args['f']['val']), 
-                array($this, 'phar_dir_echo')
-            );
-        if (!$a) {
-            echo "|-<root directory>\n";
-        }
-    }
-    // }}}
-    // {{{ cli_cmd_inf_extract
-    /**
-     * Cli Command Inf Extract
-     *
-     * @return string The description of the command extra to a directory.
-     */
-    static function cli_cmd_inf_extract()
-    {
-        return "Extract a PHAR package to a directory.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_extract
-    /**
-     * Cli Command Arguments Extract
-     * 
-     * The arguments for the extract function.
-     *
-     * @return array  The arguments for the extraction.
-     */
-    static function cli_cmd_arg_extract()
-    {
-        $args = self::phar_args('Fix', 'phar');
-        
-        $args[''] = array(
-            'type' => 'dir',  
-            'val' => '.',                 
-            'inf' => '         Directory to extract to (defaults to \'.\').',
-        );
-        
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_extract
-    /**
-     * Run Extract
-     * 
-     * Run the extraction of a phar Archive.
-     *
-     * @see $this->phar_dir_operation
-     */
-    public function cli_cmd_run_extract()
-    {
-        $dir = $this->args['']['val'];
-        
-        if (is_array($dir)) {
-            if (count($dir) != 1) {
-                self::error("Only one target directory allowed.\n");
-            } else {
-                $dir = $dir[0];
-            }
-        }
-        
-        $phar = $this->args['f']['val'];
-        $base = $phar->getPathname();
-        $bend = strpos($base, '.phar');
-        $bend = strpos($base, '/', $bend);
-        $base = substr($base, 0, $bend + 1);
-        $blen = strlen($base);
-
-        $this->phar_dir_operation(
-            new RecursiveIteratorIterator($phar), 
-            array($this, 'phar_dir_extract'), 
-            array($blen, $dir)
-        );
-    }
-    // }}}
-    // {{{ public function phar_dir_extract
-    /**
-     * Extract to a directory
-     * 
-     * This function will extract the content of a Phar
-     * to a directory and create new files and directories
-     * depending on the permissions on that folder.
-     *
-     * @param string $pn
-     * @param string $f     The file name
-     * @param array $args   The directory and Blen informations
-     */
-    public function phar_dir_extract($pn, $f, $args)
-    {
-        $blen   = $args[0];
-        $dir    = $args[1];
-        $sub    = substr($pn, $blen);
-        $target = $dir . '/' . $sub;
-        
-        if (!file_exists(dirname($target))) {
-            if (!is_writable(dirname($target))) {
-                self::error("Operation could not be completed\n");
-            }
-            
-            mkdir(dirname($target));
-        }
-        
-        echo "$sub";
-        
-        if (!@copy($f, $target)) {
-            echo " ...error\n";
-        } else {
-            echo " ...ok\n";
-        }
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_delete
-    /**
-     * Delete an entry from a phar information.
-     *
-     * @return string The information
-     */
-    static function cli_cmd_inf_delete()
-    {
-        return 'Delete entry from a PHAR archive';
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_delete
-    /**
-     * The cli command argument for deleting.
-     *
-     * @return array informations about the arguments to use.
-     */
-    static function cli_cmd_arg_delete()
-    {
-        return self::phar_args('FE', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_delete
-    /**
-     * Deleting execution
-     *
-     * Execute the deleting of the file from the phar archive.
-     */
-    public function cli_cmd_run_delete()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-
-       $phar->startBuffering();
-       unset($phar[$entry]);
-       $phar->stopBuffering();
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_add
-    /**
-     * Client comment add file information
-     *
-     * @return string The description of the feature
-     */
-    static function cli_cmd_inf_add()
-    {
-        return "Add entries to a PHAR package.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_add
-    /**
-     * Add a file arguments
-     */
-    static function cli_cmd_arg_add()
-    {
-        $args = self::phar_args('acFilx', 'phar');
-        $args[''] = array(
-            'type'     => 'any',     
-            'val'      => NULL,      
-            'required' => 1, 
-            'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
-        );
-        return $args;
-    }
-    // }}}
-    // {{{ public functio cli_cmd_run_add
-    /**
-     * Add a file
-     *
-     * Run the action of adding a file to
-     * a phar archive.
-     */
-    public function cli_cmd_run_add()
-    {
-        $compress= $this->args['c']['val'];
-        $phar    = $this->args['f']['val'];
-        $regex   = $this->args['i']['val'];
-        $level   = $this->args['l']['val'];
-        $invregex= $this->args['x']['val'];
-        $input   = $this->args['']['val'];
-
-        $phar->startBuffering();
-
-        if (!is_array($input)) {
-            $this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
-        } else {
-            foreach($input as $i) {
-                $this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
-            }
-        }
-        $phar->stopBuffering();
-        exit(0);
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_stub_set
-    /**
-     * Set the stup of a phar file.
-     *
-     * @return string The stub set description.
-     */
-    public function cli_cmd_inf_stub_set()
-    {
-        return "Set the stub of a PHAR file. " . 
-               "If no input file is specified as stub then stdin is being used.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_stub_set
-    /**
-     * Set the argument stub
-     *
-     * @return string arguments for a stub 
-     */
-    public function cli_cmd_arg_stub_set()
-    {
-        $args = self::phar_args('bFps', 'phar');
-        $args['s']['val'] = 'php://stdin';
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_stub_set
-    /**
-     * Cli Command run stub set
-     *
-     * @see   $phar->setStub()
-     */
-    public function cli_cmd_run_stub_set()
-    {
-        $hashbang = $this->args['b']['val'];
-        $phar     = $this->args['f']['val'];
-        $stub     = $this->args['s']['val'];
-        $loader   = $this->args['p']['val'];
-
-        $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
-        $this->phar_set_stub_end($phar, $stub, $loader);
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_stub_get
-    /**
-     * Get the command stub infos.
-     *
-     * @return string a description of the stub of a Phar file.
-     */
-    public function cli_cmd_inf_stub_get()
-    {
-        return "Get the stub of a PHAR file. " .  
-               "If no output file is specified as stub then stdout is being used.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_stub_get
-    /**
-     * Get the argument stub
-     *
-     * @return array $args The arguments passed to the stub.
-     */
-    public function cli_cmd_arg_stub_get()
-    {
-        $args = self::phar_args('Fs', 'phar');
-        $args['s']['val'] = 'php://stdin';
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_stub_get
-    /**
-     * Cli Command Run Stub
-     * 
-     * Get arguments and store them into a stub.
-     *
-     * @param arguments $args
-     * @see   $this->args
-     */
-    public function cli_cmd_run_stub_get($args)
-    {
-        $phar = $this->args['f']['val'];
-        $stub = $this->args['s']['val'];
-
-        file_put_contents($stub, $phar->getStub());
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_compress
-    /**
-     * Cli Command Inf Compress
-     * 
-     * Cli Command compress informations
-     *
-     * @return string A description of the command.
-     */
-    public function cli_cmd_inf_compress()
-    {
-        return "Compress or uncompress all files or a selected entry.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_cmpress
-    /**
-     * Cli Command Arg Compress
-     *
-     * @return array The arguments for compress
-     */
-    public function cli_cmd_arg_compress()
-    {
-        return self::phar_args('FCe', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_compress
-    /**
-     * Cli Command Run Compress
-     *
-     * @see $this->args
-     */
-    public function cli_cmd_run_compress()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-
-        switch($this->args['c']['val']) {
-            case 'gz':
-            case 'gzip':
-                if (isset($entry)) {
-                    $phar[$entry]->setCompressedGZ();
-                } else {
-                    $phar->compressAllFilesGZ();
-                }
-                break;
-            case 'bz2':
-            case 'bzip2':
-                if (isset($entry)) {
-                    $phar[$entry]->setCompressedBZIP2();
-                } else {
-                    $phar->compressAllFilesBZIP2();
-                }
-                break;
-            default:
-                if (isset($entry)) {
-                    $phar[$entry]->setUncompressed();
-                } else {
-                    $phar->uncompressAllFiles();
-                }
-                break;
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_sign
-    /**
-     * Cli Command Info Signature
-     *
-     * @return string A description of the signature arguments.
-     */
-    public function cli_cmd_inf_sign()
-    {
-        return "Set signature hash algorithm.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_sign
-    /**
-     * Cli Command Argument Sign
-     *
-     * @return array Arguments for Signature
-     */
-    public function cli_cmd_arg_sign()
-    {
-        return self::phar_args('FH', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_sign
-    /**
-     * Cli Command Run Signature
-     *
-     * @see $phar->setSignaturealgorithm
-     */
-    public function cli_cmd_run_sign()
-    {
-        $phar = $this->args['f']['val'];
-        $hash = $this->args['h']['val'];
-
-        $phar->setSignatureAlgorithm($hash);
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_meta_set
-    /**
-     * Cli Command Inf Meta Set
-     *
-     * @return string A description 
-     */
-    public function cli_cmd_inf_meta_set()
-    {
-        return "Set meta data of a PHAR entry or a PHAR package using serialized input. " . 
-               "If no input file is specified for meta data then stdin is being used." . 
-               "You can also specify a particular index using -k. In that case the metadata is " .
-               "expected to be an array and the value of the given index is being set. If " .
-               "the metadata is not present or empty a new array will be created. If the " .
-               "metadata is present and a flat value then the return value is 1. Also using -k " .
-               "the input is been taken directly rather then being serialized.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_set
-    /**
-     * Cli Command Argument Meta Set
-     *
-     * @return array  The arguments for meta set
-     */
-    public function cli_cmd_arg_meta_set()
-    {
-        return self::phar_args('FekM', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_met_set
-    /**
-     * Cli Command Run Metaset
-     *
-     * @see $phar->startBuffering
-     * @see $phar->setMetadata
-     * @see $phar->stopBuffering
-     */
-    public function cli_cmd_run_meta_set()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-        $meta  = $this->args['m']['val'];
-
-        $phar->startBuffering();
-
-        if (isset($index)) {
-            if (isset($entry)) {
-                if ($phar[$entry]->hasMetadata()) {
-                    $old = $phar[$entry]->getMetadata();
-                } else {
-                    $old = array();
-                }
-            } else {
-                if ($phar->hasMetadata()) {
-                    $old = $phar->getMetadata();
-                } else {
-                    $old = array();
-                }
-            }
-
-            if (!is_array($old)) {
-                self::error('Metadata is a flat value while an index operation was issued.');
-            }
-
-            $old[$index] = $meta;
-            $meta = $old;
-        } else {
-            $meta = unserialize($meta);
-        }
-        
-        if (isset($entry)) {
-            $phar[$entry]->setMetadata($meta);
-        } else {
-            $phar->setMetadata($meta);
-        }
-        $phar->stopBuffering();
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_met_get
-    /**
-     * Cli Command Inf Metaget
-     *
-     * @return string A description of the metaget arguments
-     */
-    public function cli_cmd_inf_meta_get()
-    {
-        return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
-               "If no output file is specified for meta data then stdout is being used.\n" . 
-               "You can also specify a particular index using -k. In that case the metadata is " .
-               "expected to be an array and the value of the given index is returned using echo " .
-               "rather than using serialize. If that index does not exist or no meta data is " .
-               "present then the return value is 1.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_get
-    /**
-     * Cli Command arg metaget
-     *
-     * @return array  The arguments for meta get.
-     */
-    public function cli_cmd_arg_meta_get()
-    {
-        return self::phar_args('Fek', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_meta_get
-    /**
-     * Cli Command Run Metaget
-     *
-     * @see $this->args
-     * @see $phar[$x]->hasMetadata()
-     * @see $phar->getMetadata()
-     */
-    public function cli_cmd_run_meta_get()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-
-        if (isset($entry)) {
-            if (!$phar[$entry]->hasMetadata()) {
-                echo "No Metadata\n";
-                exit(1);
-            }
-            echo serialize($phar[$entry]->getMetadata());
-        } else {
-            if (!$phar->hasMetadata()) {
-                echo "No Metadata\n";
-                exit(1);
-            }
-            $meta = $phar->getMetadata();
-        }
-
-        if (isset($index)) {
-            if (isset($index)) {
-                if (isset($meta[$index])) {
-                    echo $meta[$index];
-                    exit(0);
-                } else {
-                    echo "No Metadata\n";
-                    exit(1);
-                }
-            } else {
-                echo serialize($meta);
-            }
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_meta_del
-    /**
-     * Cli Command Inf Metadel
-     *
-     * @return string A description of the metadel function
-     */
-    public function cli_cmd_inf_meta_del()
-    {
-        return "Delete meta information of a PHAR entry or a PHAR package.\n" . 
-               "If -k is given then the metadata is expected to be an array " . 
-               "and the given index is being deleted.\n" .
-               "If something was deleted the return value is 0 otherwise it is 1.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_del
-    /**
-     * CliC ommand Arg Metadelete
-     *
-     * @return array The arguments for metadel
-     */
-    public function cli_cmd_arg_meta_del()
-    {
-        return self::phar_args('Fek', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_meta_del
-    /**
-     * Cli Command Run MetaDel
-     *
-     * @see $phar[$x]->delMetadata()
-     * @see $phar->delMetadata()
-     */
-    public function cli_cmd_run_meta_del()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-
-        if (isset($entry)) {
-            if (isset($index)) {
-                if (!$phar[$entry]->hasMetadata()) {
-                    exit(1);
-                }
-                $meta = $phar[$entry]->getMetadata();
-
-                // @todo add error message here.
-                if (!is_array($meta)) {
-                    exit(1);
-                }
-
-                unset($meta[$index]);
-                $phar[$entry]->setMetadata($meta);
-            } else {
-                exit($phar[$entry]->delMetadata() ? 0 : 1);
-            }
-        } else {
-            if (isset($index)) {
-                if (!$phar->hasMetadata()) {
-                    exit(1);
-                }
-
-                $meta = $phar->getMetadata();
-
-                // @todo Add error message
-                if (!is_array($meta)) {
-                    exit(1);
-                }
-
-                unset($meta[$index]);
-                $phar->setMetadata($meta);
-            } else {
-                exit($phar->delMetadata() ? 0 : 1);
-            }
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_info
-    /**
-     * CLi Command Inf Info
-     *
-     * @return string A description about the info commands.
-     */
-    public function cli_cmd_inf_info()
-    {
-        return "Get information about a PHAR package.\n" . 
-               "By using -k it is possible to return a single value.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_info
-    /**
-     * Cli Command Arg Infos
-     *
-     * @return array The arguments for info command.
-     */
-    public function cli_cmd_arg_info()
-    {
-        return self::phar_args('Fk', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_info
-    /**
-     * Cli Command Run Info
-     *
-     * @param args $args
-     */
-    public function cli_cmd_run_info()
-    {
-        $phar  = $this->args['f']['val'];
-        $index = $this->args['k']['val'];
-
-        $hash  = $phar->getSignature();
-        $infos = array();
-
-        if ($phar->getAlias()) {
-            $infos['Alias'] = $phar->getAlias();
-        }
-
-        if (!$hash) {
-            $infos['Hash-type'] = 'NONE';
-        } else {
-            $infos['Hash-type'] = $hash['hash_type'];
-            $infos['Hash'] = $hash['hash'];
-        }
-
-        $csize   = 0;
-        $usize   = 0;
-        $count   = 0;
-        $ccount  = 0;
-        $ucount  = 0;
-        $mcount  = 0;
-        $compalg = array('GZ'=>0, 'BZ2'=>0);
-
-        foreach(new RecursiveIteratorIterator($phar) as $ent) {
-            $count++;
-            if ($ent->isCompressed()) {
-                $ccount++;
-                $csize += $ent->getCompressedSize();
-                if ($ent->isCompressedGZ()) {
-                    $compalg['GZ']++;
-                } elseif ($ent->isCompressedBZIP2()) {
-                    $compalg['BZ2']++;
-                }
-            } else {
-                $ucount++;
-                $csize += $ent->getSize();
-            }
-            
-            $usize += $ent->getSize();
-            
-            if ($ent->hasMetadata()) {
-                $mcount++;
-            }
-        }
-
-        $infos['Entries']            = $count;
-        $infos['Uncompressed-files'] = $ucount;
-        $infos['Compressed-files']   = $ccount;
-        $infos['Compressed-gz']      = $compalg['GZ'];
-        $infos['Compressed-bz2']     = $compalg['BZ2'];
-        $infos['Uncompressed-size']  = $usize;
-        $infos['Compressed-size']    = $csize;
-        $infos['Compression-ratio']  = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
-        $infos['Metadata-global']    = $phar->hasMetadata() * 1;
-        $infos['Metadata-files']     = $mcount;
-        $infos['Stub-size']          = strlen($phar->getStub());
-
-        if (isset($index)) {
-            if (!isset($infos[$index])) {
-                self::error("Requested value does not exist.\n");
-            }
-
-            echo $infos[$index];
-            exit(0);
-        }
-        
-        $l = 0;
-        foreach($infos as $which => $val) {
-            $l = max(strlen($which), $l);
-        }
-        
-        foreach($infos as $which => $val) {
-            echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
-        }
-    }
-    // }}}
+       // {{{ public function cli_get_SP2
+       public function cli_get_SP2($l1, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 4 + 9);
+       }
+       // }}}
+       // {{{ public function cli_get_SP3
+       /**
+        * Cli Get SP3
+        *
+        * @param string $l1      Eleven
+        * @param string $l2      Twelve
+        * @param string $arg_inf
+        * @return string  The repeated string.
+        */
+       function cli_get_SP3($l1, $l2, $arg_inf)
+       {
+               return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
+       }
+       // }}}
+       // {{{ static function phar_args
+       /**
+        * Phar arguments
+        * 
+        * This function contains all the phar commands
+        *
+        * @param  string $which    Which argument is chosen.
+        * @param  string $phartype The type of phar, specific file to work on
+        * @return unknown
+        */
+       static function phar_args($which, $phartype)
+       {
+               $phar_args = array(
+                       'a' => array(
+                               'typ' => 'alias',
+                               'val' => NULL,
+                               'inf' => '<alias>  Provide an alias name for the phar file.'
+                       ),
+                       'b' => array(
+                               'typ' => 'any',
+                               'val' => NULL,
+                               'inf' => '<bang>   Hash-bang line to start the archive (e.g. #!/usr/bin/php). The hash '
+                                                .'         mark itself \'#!\' and the newline character are optional.'
+                       ),
+                       'c' => array(
+                               'typ' => 'compalg',
+                               'val' => NULL,
+                               'inf' => '<algo>   Compression algorithm.',
+                               'select' => array(
+                                       '0'    => 'No compression',
+                                       'none' => 'No compression',
+                                       'auto' => 'Automatically select compression algorithm'
+                               )
+                       ),
+                       'e' => array(
+                               'typ' => 'entry',
+                               'val' => NULL,
+                               'inf' => '<entry>  Name of entry to work on (must include PHAR internal directory name if any).'
+                       ),
+                       'f' => array(
+                               'typ' => $phartype,
+                               'val' => NULL,
+                               'inf' => '<file>   Specifies the phar file to work on.'
+                       ),
+                       'h' => array(
+                               'typ' => 'select',
+                               'val' => NULL,
+                               'inf' => '<method> Selects the hash algorithmn.',
+                               'select' => array('md5' => 'MD5','sha1' => 'SHA1')
+                       ),
+                       'i' => array(
+                               'typ' => 'regex',
+                               'val' => NULL,
+                               'inf' => '<regex>  Specifies a regular expression for input files.'
+                       ),
+                       'k' => array(
+                               'typ' => 'any',
+                               'val' => NULL,
+                               'inf' => '<index>  Subscription index to work on.',
+                       ),
+                       'l' => array(
+                               'typ' => 'int',
+                               'val' => 0,
+                               'inf' => '<level>  Number of preceeding subdirectories to strip from file entries',
+                       ),
+                       'm' => array(
+                               'typ' => 'any',
+                               'val' => NULL,
+                               'inf' => '<meta>   Meta data to store with entry (serialized php data).'
+                       ),
+                       'p' => array(
+                               'typ' => 'loader',
+                               'val' => NULL,
+                               'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
+                                                .'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
+                                                .'pear command. When using \'0\' the command does not error out when the '
+                                                .'class file cannot be located. This switch also adds some code around the '
+                                                .'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
+                                                .'if necessary. And finally this switch will add the file phar.inc from '
+                                                .'this package and load it to ensure class Phar is present.'
+                                                ,
+                       ),
+                       's' => array(
+                               'typ' => 'file',
+                               'val' => NULL,
+                               'inf' => '<stub>   Select the stub file.'
+                       ),
+                       'x' => array(
+                               'typ' => 'regex',
+                               'val' => NULL,
+                               'inf' => '<regex>  Regular expression for input files to exclude.'
+                       ),
+                       'y' => array(
+                               'typ' => 'privkey',
+                               'val' => NULL,
+                               'inf' => 'Private key for OpenSSL signing.',
+                       ),
+               );
+
+               if (extension_loaded('zlib')) {
+                       $phar_args['c']['select']['gz']    = 'GZip compression';
+                       $phar_args['c']['select']['gzip']  = 'GZip compression';
+               }
+
+               if (extension_loaded('bz2')) {
+                       $phar_args['c']['select']['bz2']   = 'BZip2 compression';
+                       $phar_args['c']['select']['bzip2'] = 'BZip2 compression';
+               }
+
+               $hash_avail = Phar::getSupportedSignatures();
+               $hash_optional = array('SHA-256' => 'SHA256',
+                                                          'SHA-512' => 'SHA512',
+                                                          'OpenSSL' => 'OpenSSL');
+
+               foreach($hash_optional as $key => $name) {
+                       if (in_array($key, $hash_avail)) {
+                               $phar_args['h']['select'][strtolower($name)] = $name;
+                       }
+               }
+
+               $args = array();
+
+               foreach($phar_args as $lkey => $cfg) {
+                       $ukey     = strtoupper($lkey);
+                       $required = strpos($which, $ukey) !== false;
+                       $optional = strpos($which, $lkey) !== false;
+
+                       if ($required || $optional) {
+                               $args[$lkey] = $cfg;
+                               $args[$lkey]['required'] = $required;
+                       }
+               }
+               return $args;
+       }
+       // }}}
+       // {{{ static function strEndsWith
+       /**
+        * String Ends With
+        * 
+        * Whether a string ends with another needle.
+        *
+        * @param string $haystack  The haystack
+        * @param string $needle    The needle.
+        * @return mixed false if doesn't end with anything, the string
+        *               substr'ed if the string ends with the needle.
+        */
+       static function strEndsWith($haystack, $needle)
+       {
+               return substr($haystack, -strlen($needle)) == $needle;
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_loader
+       /**
+        * Argument type loader
+        *
+        * @param string $arg   Either 'auto', 'optional' or an filename that
+        *                      contains class PHP_Archive
+        * @param  string $cfg  Configuration to pass to a new file
+        * @param  string $key  The key
+        * @return string $arg  The argument.
+        */
+       static function cli_arg_typ_loader($arg, $cfg, $key)
+       {
+               if (($arg == '0' || $arg == '1') && !file_exists($arg)) {
+                       $found = NULL;
+                       $apiver = `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`;
+                       $apiver = trim(substr($apiver, strlen('API Version')));
+                       if ($apiver) {
+                               self::notice("Pear package PHP_Archive: API Version: $apiver.\n");
+                               $files  = split("\n", `pear list-files PHP_Archive`);
+                               $phpdir = `pear config-get php_dir 2>/dev/null`;
+                               $phpdir = trim($phpdir);
+                               self::notice("Pear package PHP_Archive: $phpdir.\n");
+                               if (is_dir($phpdir)) {
+                                       foreach($files as $ent) {
+                                               $matches = NULL;
+                                               if (preg_match(",^php[ \t]+([^ \t].*[\\\\/]PHP[\\\\/]Archive\.php)$,", $ent, $matches)) {
+                                                       $sub = $matches[1];
+                                                       if (strpos($sub, $phpdir) !== 0) {
+                                                               $found = NULL;
+                                                               break;
+                                                       }
+                                                       $found = $sub;
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       self::notice("Pear package PHP_Archive: corrupt or inaccessible base dir: $php_dir.\n");
+                               }
+                       }
+                       if (isset($found)) {
+                               self::notice("Pear package PHP_Archive: $found.\n");
+                       } else {
+                               $msg = "Pear package PHP_Archive or Archive.php class file not found.\n";
+                               if ($arg == '0') {
+                                       self::notice($msg);
+                               } else {
+                                       self::error($msg);
+                               }
+                       }
+                       $arg = $found;
+               }
+               return self::cli_arg_typ_file($arg);
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_pharnew
+       /**
+        * Argument type new phar
+        *
+        * @param  string $arg  The new phar component.
+        * @param  string $cfg  Configuration to pass to a new file
+        * @param  string $key  The key
+        * @return string $arg  The new argument file.
+        */
+       static function cli_arg_typ_pharnew($arg, $cfg, $key)
+       {
+               $arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
+               if (!Phar::isValidPharFilename($arg)) {
+                       self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or '.phar.gz'.\n");
+               }
+               return $arg;
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_pharfile
+       /**
+        * Argument type existing Phar file
+        * 
+        * Return filename of an existing Phar.
+        *
+        * @param  string $arg      The file in the phar to open.
+        * @param  string $cfg      The configuration information
+        * @param  string $key      The key information.
+        * @return string $pharfile The name of the loaded Phar file.
+        * @note The Phar will be loaded
+        */
+       static function cli_arg_typ_pharfile($arg, $cfg, $key)
+       {
+               try {
+                       $pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
+
+                       if (!Phar::loadPhar($pharfile)) {
+                               self::error("Unable to open phar '$arg'\n");
+                       }
+
+                       return $pharfile;
+               } catch(Exception $e) {
+                       self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
+               }
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_pharurl
+       /**
+        * Argument type Phar url-like
+        * 
+        * Check the argument as cli_arg_Typ_phar and return its name prefixed
+        * with phar://
+        * 
+        * Ex:
+        * <code>
+        *  $arg = 'pharchive.phar/file.php';
+        *  cli_arg_typ_pharurl($arg)
+        * </code>
+        *
+        * @param  string $arg The url-like phar archive to retrieve.
+        * @return string The phar file-archive.
+        */
+       static function cli_arg_typ_pharurl($arg, $cfg, $key)
+       {
+               return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_phar
+       /**
+        * Cli argument type phar
+        *
+        * @param  string $arg  The phar archive to use.
+        * @return object new Phar of the passed argument.
+        */
+       static function cli_arg_typ_phar($arg, $cfg, $key)
+       {
+               try {
+                       return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
+               } catch(Exception $e) {
+                       self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
+               }
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_entry
+       /**
+        * Argument type Entry name
+        *
+        * @param  string $arg The argument (the entry)
+        * @return string $arg The entry itself.
+        */
+       static function cli_arg_typ_entry($arg, $cfg, $key)
+       {
+               // no further check atm, maybe check for no '/' at beginning
+               return $arg;
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_compalg
+       /**
+        * Argument type compression algorithm
+        *
+        * @param  string $arg  The phar selection
+        * @param  string $cfg  The config option.
+        * @param  string $key  The key information.
+        * @return string $arg  The selected algorithm
+        */
+       static function cli_arg_typ_compalg($arg, $cfg, $key)
+       {
+               $arg = self::cli_arg_typ_select($arg, $cfg, $key);
+
+               switch($arg) {
+                       case 'auto':
+                               if (extension_loaded('zlib')) {
+                                       $arg = 'gz';
+                               } elseif (extension_loaded('bz2')) {
+                                       $arg = 'bz2';
+                               } else {
+                                       $arg = '0';
+                               }
+                               break;
+               }
+               return $arg;
+       }
+       // }}}
+       // {{{ static function cli_arg_typ_privkey
+       /**
+        * Argument type private key (for OpenSSL signing)
+        *
+        * @param  string $arg  The phar selection
+        * @param  string $cfg  The config option.
+        * @param  string $key  The key information.
+        * @return string $arg  The selected algorithm
+        */
+       static function cli_arg_typ_privkey($arg, $cfg, $key)
+       {
+               $arg = self::cli_arg_typ_string($arg, $cfg, $key);
+
+               $hash_avail = Phar::getSupportedSignatures();
+               if ($arg && !in_array('OpenSSL', $hash_avail))
+               {
+                       self::error("Cannot specifiy private key without OpenSSL support.\n");
+               }
+               return $arg;
+       }
+       // }}}
+       // {{{ static function phar_check_hash
+       /**
+        * Check whether hash method is valid.
+        *
+        * @return Hash constant to be used.
+        */
+       function phar_check_hash($hash, $privkey)
+       {
+               switch($hash) {
+                       case 'md5':
+                               return Phar::MD5;
+                       case 'sha1':
+                               return Phar::SHA1;
+                       case 'sha256':
+                               return Phar::SHA256;
+                       case 'sha512':
+                               return Phar::SHA512;
+                       case 'openssl':
+                               if (!$privkey) {
+                                       self::error("Cannot use OpenSSL signing without key.\n");
+                               }
+                               return Phar::OPENSSL;
+               }
+       }
+       // }}}
+       // {{{ static function cli_cmd_inf_pack
+       /**
+        * Information pack
+        *
+        * @return string A description about packing files into a Phar archive.
+        */
+       static function cli_cmd_inf_pack()
+       {
+               return "Pack files into a PHAR archive.\n" .
+                          "When using -s <stub>, then the stub file is being " .
+                          "excluded from the list of input files/dirs." .
+                          "To create an archive that contains PEAR class PHP_Archive " .
+                          "then point -p argument to PHP/Archive.php.\n";
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_pack
+       /**
+        * Pack a new phar infos
+        *
+        * @return array  $args  The arguments for a new Phar archive.
+        */
+       static function cli_cmd_arg_pack()
+       {
+               $args = self::phar_args('abcFhilpsxy', 'pharnew');
+
+               $args[''] = array(
+                       'typ'     => 'any',
+                       'val'      => NULL,
+                       'required' => 1,
+                       'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
+               );
+
+               return $args;
+       }
+       // }}}
+       // {{{ function phar_set_stub_begin
+       /**
+        * Set the stub
+        */
+       public function phar_set_stub_begin(Phar $phar, $stub, $loader = NULL, $hashbang = NULL)
+       {
+               if (isset($stub)) {
+                       $c = file_get_contents($stub);
+
+                       if (substr($c, 0, 2) == '#!') {
+                               if (strpos($c, "\n") !== false) {
+                                       if (!isset($hashbang)) {
+                                               $hashbang = substr($c, 0, strpos($c, "\n") + 1);
+                                       }
+                                       $c = substr($c, strpos($c, "\n") + 1);
+                               } else {
+                                       if (!isset($hashbang)) {
+                                               $hashbang = $c;
+                                       }
+                                       $c = NULL;
+                               }
+                       }
+
+                       if (isset($hashbang)) {
+                               if (substr($hashbang, 0, 2) != '#!') {
+                                       $hashbang = '#!' . $hashbang;
+                               }
+                               if (substr($hashbang, -1) != "\n") {
+                                       $hashbang .= "\n";
+                               }
+                       } else {
+                               $hashbang = "";
+                       }
+
+                       if (isset($loader)) {
+                               $s = "<?php if (!class_exists('PHP_Archive')) {\n?>";
+                               $s .= file_get_contents($loader);
+                               $s .= "<?php\n";
+                               $s .= "}\n";
+                               $s .= "if (!in_array('phar', stream_get_wrappers())) {\n";
+                               $s .= "\tstream_wrapper_register('phar', 'PHP_Archive');\n";
+                               $s .= "}\n";
+                               $s .= "if (!class_exists('Phar',0)) {\n";
+                               $s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
+                               $s .= "}\n";
+                               $s .= '?>';
+                               $s .= $c;
+
+                               $phar->setStub($hashbang . $s);
+                       } else {
+                               $phar->setStub($hashbang . $c);
+                       }
+                       return new SplFileInfo($stub);
+               }
+               return NULL;
+       }
+       // }}}
+       // {{{ function phar_set_stub_end
+       /**
+        * Set stub end
+        */
+       public function phar_set_stub_end(Phar $phar, $stub, $loader = NULL)
+       {
+               if (isset($stub) && isset($loader)) {
+                       if (substr(__FILE__, -15) == 'pharcommand.inc') {
+                               self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
+                       } else {
+                               self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
+                       }
+               }
+       }
+       // }}}
+       // {{{ function cli_cmd_run_pack
+       /**
+        * Pack a new Phar
+        * 
+        * This function will try to pack a new Phar archive.
+        * 
+        * @see Exit to make sure that we are done.
+        */
+       public function cli_cmd_run_pack()
+       {
+               if (ini_get('phar.readonly')) {
+                       self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
+               }
+
+               if (!Phar::canWrite()) {
+                       self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
+               }
+
+               $alias    = $this->args['a']['val'];
+               $hashbang = $this->args['b']['val'];
+               $archive  = $this->args['f']['val'];
+               $hash     = $this->args['h']['val'];
+               $privkey  = $this->args['y']['val'];
+               $regex    = $this->args['i']['val'];
+               $level    = $this->args['l']['val'];
+               $loader   = $this->args['p']['val'];
+               $stub     = $this->args['s']['val'];
+               $invregex = $this->args['x']['val'];
+               $input    = $this->args['']['val'];
+
+               $hash = self::phar_check_hash($hash, $privkey);
+
+               $phar  = new Phar($archive, 0, $alias);
+
+               $phar->startBuffering();
+
+               $stub = $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
+
+               if (!is_array($input)) {
+                       $this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
+               } else {
+                       foreach($input as $i) {
+                               $this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
+                       }
+               }
+
+               $this->phar_set_stub_end($phar, $stub, $loader);
+
+               switch($this->args['c']['val']) {
+                       case 'gz':
+                       case 'gzip':
+                               $phar->compressFiles(Phar::GZ);
+                               break;
+                       case 'bz2':
+                       case 'bzip2':
+                               $phar->compressFiles(Phar::BZ2);
+                               break;
+                       default:
+                               $phar->decompressFiles();
+                               break;
+               }
+
+               if ($hash) {
+                       $phar->setSignatureAlgorithm($hash, $privkey);
+               }
+
+               $phar->stopBuffering();
+               exit(0);
+       }
+       // }}}
+       // {{{ static function phar_add
+       /**
+        * Add files to a phar archive.
+        *
+        * This function will take a directory and iterate through
+        * it and get the files to insert into the Phar archive.
+        * 
+        * @param Phar        $phar      The phar object.
+        * @param string      $input     The input directory
+        * @param string      $regex     The regex used in RegexIterator.
+        * @param string      $invregex  The InvertedRegexIterator expression.
+        * @param SplFileInfo $stub Stub file object
+        * @param mixed       $compress  Compression algorithm or NULL
+        * @param boolean     $noloader  Whether to prevent adding the loader
+        */
+       static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
+       {
+               if ($input && is_file($input) && !is_dir($input)) {
+                       return self::phar_add_file($phar, $level, $input, $input, $compress);
+               }
+               $dir   = new RecursiveDirectoryIterator($input);
+               $dir   = new RecursiveIteratorIterator($dir);
+
+               if (isset($regex)) {
+                       $dir = new RegexIterator($dir, $regex);
+               }
+
+               if (isset($invregex)) {
+                       $dir = new InvertedRegexIterator($dir, $invregex);
+               }
+
+               try {
+                       foreach($dir as $file) {
+                               if ((empty($stub) || $file->getRealPath() != $stub->getRealPath()) && !is_dir($file)) {
+                                       self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
+                               }
+                       }
+               } catch(Excpetion $e) {
+                       self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
+               }
+       }
+       // }}}
+       // {{{ static function phar_add_file
+       /**
+        * Add a phar file
+        *
+        * This function adds a file to a phar archive.
+        *
+        * @param Phar    $phar      The phar object
+        * @param string  $level     The level of the file.
+        * @param string  $entry     The entry point
+        * @param string  $file      The file to add to the archive
+        * @param string  $compress  The compression scheme for the file.
+        * @param boolean $noloader  Whether to prevent adding the loader
+        */
+       static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
+       {
+               $entry = str_replace('//', '/', $entry);
+               while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
+                       $entry = substr($entry, $p+1);
+               }
+
+       if ($noloader && $entry == 'phar.inc') {
+               return;
+       }
+
+               echo "$entry\n";
+
+               $phar[$entry] = file_get_contents($file);
+               switch($compress) {
+                       case 'gz':
+                       case 'gzip':
+                               $phar[$entry]->compress(Phar::GZ);
+                               break;
+                       case 'bz2':
+                       case 'bzip2':
+                               $phar[$entry]->compress(Phar::BZ2);
+                               break;
+                       case '0':
+                               $phar[$entry]->decompress();
+                               break;
+                       default:
+                               break;
+               }
+       }
+       // }}}
+       // {{{ public function phar_dir_echo
+       /**
+        * Echo directory
+        *
+        * @param string $pn
+        * @param unknown_type $f
+        */
+       public function phar_dir_echo($pn, $f)
+       {
+               echo "$f\n";
+       }
+       // }}}
+       // {{{ public function phar_dir_operation
+       /**
+        * Directory operations
+        * 
+        * Phar directory operations.
+        *
+        * @param RecursiveIteratorIterator $dir  The recursiveIteratorIterator object.
+        * @param string                    $func Function to call on the iterations
+        * @param array                     $args Function arguments.
+        */
+       public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
+       {
+               $regex   = $this->args['i']['val'];
+               $invregex= $this->args['x']['val'];
+
+               if (isset($regex)) {
+                       $dir = new RegexIterator($dir, $regex);
+               }
+
+               if (isset($invregex)) {
+                       $dir = new InvertedRegexIterator($dir, $invregex);
+               }
+
+               $any = false;
+               foreach($dir as $pn => $f) {
+                       $any = true;
+                       call_user_func($func, $pn, $f, $args);
+               }
+               return $any;
+       }
+       // {{{ static function cli_cmd_inf_list
+       /**
+        * Cli Command Info List
+        *
+        * @return string What inf does
+        */
+       static function cli_cmd_inf_list()
+       {
+               return "List contents of a PHAR archive.";
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_list
+       /**
+        * Cli Command Argument List
+        *
+        * @return arguments list
+        */
+       static function cli_cmd_arg_list()
+       {
+               return self::phar_args('Fix', 'pharurl');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_list
+       /**
+        * Cli Command Run List
+        *
+        * @see $this->phar_dir_operation
+        */
+       public function cli_cmd_run_list()
+       {
+               $this->phar_dir_operation(
+                       new DirectoryTreeIterator(
+                               $this->args['f']['val']),
+                               array($this, 'phar_dir_echo')
+                       );
+       }
+       // }}}
+       // {{{ static function cli_command_inf_tree
+       /**
+        * Cli Command Inf Tree
+        *
+        * @return string  The description of a directory tree for a Phar archive.
+        */
+       static function cli_cmd_inf_tree()
+       {
+               return "Get a directory tree for a PHAR archive.";
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_tree
+       /**
+        * Cli Command Argument Tree
+        *
+        * @return string Arguments in URL format.
+        */
+       static function cli_cmd_arg_tree()
+       {
+               return self::phar_args('Fix', 'pharurl');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_tree
+       /**
+        * Cli Command Run Tree
+        * 
+        * Set the phar_dir_operation with a directorygraphiterator.
+        * 
+        * @see DirectoryGraphIterator
+        * @see $this->phar_dir_operation
+        *
+        */
+       public function cli_cmd_run_tree()
+       {
+               $a = $this->phar_dir_operation(
+                       new DirectoryGraphIterator(
+                               $this->args['f']['val']),
+                               array($this, 'phar_dir_echo')
+                       );
+               if (!$a) {
+                       echo "|-<root directory>\n";
+               }
+       }
+       // }}}
+       // {{{ cli_cmd_inf_extract
+       /**
+        * Cli Command Inf Extract
+        *
+        * @return string The description of the command extra to a directory.
+        */
+       static function cli_cmd_inf_extract()
+       {
+               return "Extract a PHAR package to a directory.";
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_extract
+       /**
+        * Cli Command Arguments Extract
+        * 
+        * The arguments for the extract function.
+        *
+        * @return array  The arguments for the extraction.
+        */
+       static function cli_cmd_arg_extract()
+       {
+               $args = self::phar_args('Fix', 'phar');
+
+               $args[''] = array(
+                       'type' => 'dir',
+                       'val' => '.',
+                       'inf' => '         Directory to extract to (defaults to \'.\').',
+               );
+
+               return $args;
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_extract
+       /**
+        * Run Extract
+        * 
+        * Run the extraction of a phar Archive.
+        *
+        * @see $this->phar_dir_operation
+        */
+       public function cli_cmd_run_extract()
+       {
+               $dir = $this->args['']['val'];
+
+               if (is_array($dir)) {
+                       if (count($dir) != 1) {
+                               self::error("Only one target directory allowed.\n");
+                       } else {
+                               $dir = $dir[0];
+                       }
+               }
+
+               $phar = $this->args['f']['val'];
+               $base = $phar->getPathname();
+               $bend = strpos($base, '.phar');
+               $bend = strpos($base, '/', $bend);
+               $base = substr($base, 0, $bend + 1);
+               $blen = strlen($base);
+
+               $this->phar_dir_operation(
+                       new RecursiveIteratorIterator($phar),
+                       array($this, 'phar_dir_extract'),
+                       array($blen, $dir)
+               );
+       }
+       // }}}
+       // {{{ public function phar_dir_extract
+       /**
+        * Extract to a directory
+        * 
+        * This function will extract the content of a Phar
+        * to a directory and create new files and directories
+        * depending on the permissions on that folder.
+        *
+        * @param string $pn
+        * @param string $f     The file name
+        * @param array $args   The directory and Blen informations
+        */
+       public function phar_dir_extract($pn, $f, $args)
+       {
+               $blen   = $args[0];
+               $dir    = $args[1];
+               $sub    = substr($pn, $blen);
+               $target = $dir . '/' . $sub;
+
+               if (!file_exists(dirname($target))) {
+                       if (!is_writable(dirname($target))) {
+                               self::error("Operation could not be completed\n");
+                       }
+
+                       mkdir(dirname($target));
+               }
+
+               echo "$sub";
+
+               if (!@copy($f, $target)) {
+                       echo " ...error\n";
+               } else {
+                       echo " ...ok\n";
+               }
+       }
+       // }}}
+       // {{{ static function cli_cmd_inf_delete
+       /**
+        * Delete an entry from a phar information.
+        *
+        * @return string The information
+        */
+       static function cli_cmd_inf_delete()
+       {
+               return 'Delete entry from a PHAR archive';
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_delete
+       /**
+        * The cli command argument for deleting.
+        *
+        * @return array informations about the arguments to use.
+        */
+       static function cli_cmd_arg_delete()
+       {
+               return self::phar_args('FE', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_delete
+       /**
+        * Deleting execution
+        *
+        * Execute the deleting of the file from the phar archive.
+        */
+       public function cli_cmd_run_delete()
+       {
+               $phar  = $this->args['f']['val'];
+               $entry = $this->args['e']['val'];
+
+               $phar->startBuffering();
+               unset($phar[$entry]);
+               $phar->stopBuffering();
+       }
+       // }}}
+       // {{{ static function cli_cmd_inf_add
+       /**
+        * Client comment add file information
+        *
+        * @return string The description of the feature
+        */
+       static function cli_cmd_inf_add()
+       {
+               return "Add entries to a PHAR package.";
+       }
+       // }}}
+       // {{{ static function cli_cmd_arg_add
+       /**
+        * Add a file arguments
+        */
+       static function cli_cmd_arg_add()
+       {
+               $args = self::phar_args('acFilx', 'phar');
+               $args[''] = array(
+                       'type'     => 'any',
+                       'val'      => NULL,
+                       'required' => 1,
+                       'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
+               );
+               return $args;
+       }
+       // }}}
+       // {{{ public functio cli_cmd_run_add
+       /**
+        * Add a file
+        *
+        * Run the action of adding a file to
+        * a phar archive.
+        */
+       public function cli_cmd_run_add()
+       {
+               $compress= $this->args['c']['val'];
+               $phar    = $this->args['f']['val'];
+               $regex   = $this->args['i']['val'];
+               $level   = $this->args['l']['val'];
+               $invregex= $this->args['x']['val'];
+               $input   = $this->args['']['val'];
+
+               $phar->startBuffering();
+
+               if (!is_array($input)) {
+                       $this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
+               } else {
+                       foreach($input as $i) {
+                               $this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
+                       }
+               }
+               $phar->stopBuffering();
+               exit(0);
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_stub_set
+       /**
+        * Set the stup of a phar file.
+        *
+        * @return string The stub set description.
+        */
+       public function cli_cmd_inf_stub_set()
+       {
+               return "Set the stub of a PHAR file. " .
+                          "If no input file is specified as stub then stdin is being used.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_stub_set
+       /**
+        * Set the argument stub
+        *
+        * @return string arguments for a stub
+        */
+       public function cli_cmd_arg_stub_set()
+       {
+               $args = self::phar_args('bFps', 'phar');
+               $args['s']['val'] = 'php://stdin';
+               return $args;
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_stub_set
+       /**
+        * Cli Command run stub set
+        *
+        * @see   $phar->setStub()
+        */
+       public function cli_cmd_run_stub_set()
+       {
+               $hashbang = $this->args['b']['val'];
+               $phar     = $this->args['f']['val'];
+               $stub     = $this->args['s']['val'];
+               $loader   = $this->args['p']['val'];
+
+               $this->phar_set_stub_begin($phar, $stub, $loader, $hashbang);
+               $this->phar_set_stub_end($phar, $stub, $loader);
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_stub_get
+       /**
+        * Get the command stub infos.
+        *
+        * @return string a description of the stub of a Phar file.
+        */
+       public function cli_cmd_inf_stub_get()
+       {
+               return "Get the stub of a PHAR file. " .
+                          "If no output file is specified as stub then stdout is being used.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_stub_get
+       /**
+        * Get the argument stub
+        *
+        * @return array $args The arguments passed to the stub.
+        */
+       public function cli_cmd_arg_stub_get()
+       {
+               $args = self::phar_args('Fs', 'phar');
+               $args['s']['val'] = 'php://stdin';
+               return $args;
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_stub_get
+       /**
+        * Cli Command Run Stub
+        * 
+        * Get arguments and store them into a stub.
+        *
+        * @param arguments $args
+        * @see   $this->args
+        */
+       public function cli_cmd_run_stub_get($args)
+       {
+               $phar = $this->args['f']['val'];
+               $stub = $this->args['s']['val'];
+
+               file_put_contents($stub, $phar->getStub());
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_compress
+       /**
+        * Cli Command Inf Compress
+        * 
+        * Cli Command compress informations
+        *
+        * @return string A description of the command.
+        */
+       public function cli_cmd_inf_compress()
+       {
+               return "Compress or uncompress all files or a selected entry.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_cmpress
+       /**
+        * Cli Command Arg Compress
+        *
+        * @return array The arguments for compress
+        */
+       public function cli_cmd_arg_compress()
+       {
+               return self::phar_args('FCe', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_compress
+       /**
+        * Cli Command Run Compress
+        *
+        * @see $this->args
+        */
+       public function cli_cmd_run_compress()
+       {
+               $phar  = $this->args['f']['val'];
+               $entry = $this->args['e']['val'];
+
+               switch($this->args['c']['val']) {
+                       case 'gz':
+                       case 'gzip':
+                               if (isset($entry)) {
+                                       $phar[$entry]->compress(Phar::GZ);
+                               } else {
+                                       $phar->compressFiles(Phar::GZ);
+                               }
+                               break;
+                       case 'bz2':
+                       case 'bzip2':
+                               if (isset($entry)) {
+                                       $phar[$entry]->compress(Phar::BZ2);
+                               } else {
+                                       $phar->compressFiles(Phar::BZ2);
+                               }
+                               break;
+                       default:
+                               if (isset($entry)) {
+                                       $phar[$entry]->decompress();
+                               } else {
+                                       $phar->decompressFiles();
+                               }
+                               break;
+               }
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_sign
+       /**
+        * Cli Command Info Signature
+        *
+        * @return string A description of the signature arguments.
+        */
+       public function cli_cmd_inf_sign()
+       {
+               return "Set signature hash algorithm.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_sign
+       /**
+        * Cli Command Argument Sign
+        *
+        * @return array Arguments for Signature
+        */
+       public function cli_cmd_arg_sign()
+       {
+               return self::phar_args('FHy', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_sign
+       /**
+        * Cli Command Run Signature
+        *
+        * @see $phar->setSignaturealgorithm
+        */
+       public function cli_cmd_run_sign()
+       {
+               $phar     = $this->args['f']['val'];
+               $hash     = $this->args['h']['val'];
+               $privkey  = $this->args['y']['val'];
+
+               $hash = self::phar_check_hash($hash, $privkey);
+
+               $phar->setSignatureAlgorithm($hash, $privkey);
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_meta_set
+       /**
+        * Cli Command Inf Meta Set
+        *
+        * @return string A description
+        */
+       public function cli_cmd_inf_meta_set()
+       {
+               return "Set meta data of a PHAR entry or a PHAR package using serialized input. " .
+                          "If no input file is specified for meta data then stdin is being used." .
+                          "You can also specify a particular index using -k. In that case the metadata is " .
+                          "expected to be an array and the value of the given index is being set. If " .
+                          "the metadata is not present or empty a new array will be created. If the " .
+                          "metadata is present and a flat value then the return value is 1. Also using -k " .
+                          "the input is been taken directly rather then being serialized.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_meta_set
+       /**
+        * Cli Command Argument Meta Set
+        *
+        * @return array  The arguments for meta set
+        */
+       public function cli_cmd_arg_meta_set()
+       {
+               return self::phar_args('FekM', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_met_set
+       /**
+        * Cli Command Run Metaset
+        *
+        * @see $phar->startBuffering
+        * @see $phar->setMetadata
+        * @see $phar->stopBuffering
+        */
+       public function cli_cmd_run_meta_set()
+       {
+               $phar  = $this->args['f']['val'];
+               $entry = $this->args['e']['val'];
+               $index = $this->args['k']['val'];
+               $meta  = $this->args['m']['val'];
+
+               $phar->startBuffering();
+
+               if (isset($index)) {
+                       if (isset($entry)) {
+                               if ($phar[$entry]->hasMetadata()) {
+                                       $old = $phar[$entry]->getMetadata();
+                               } else {
+                                       $old = array();
+                               }
+                       } else {
+                               if ($phar->hasMetadata()) {
+                                       $old = $phar->getMetadata();
+                               } else {
+                                       $old = array();
+                               }
+                       }
+
+                       if (!is_array($old)) {
+                               self::error('Metadata is a flat value while an index operation was issued.');
+                       }
+
+                       $old[$index] = $meta;
+                       $meta = $old;
+               } else {
+                       $meta = unserialize($meta);
+               }
+
+               if (isset($entry)) {
+                       $phar[$entry]->setMetadata($meta);
+               } else {
+                       $phar->setMetadata($meta);
+               }
+               $phar->stopBuffering();
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_met_get
+       /**
+        * Cli Command Inf Metaget
+        *
+        * @return string A description of the metaget arguments
+        */
+       public function cli_cmd_inf_meta_get()
+       {
+               return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
+                          "If no output file is specified for meta data then stdout is being used.\n" .
+                          "You can also specify a particular index using -k. In that case the metadata is " .
+                          "expected to be an array and the value of the given index is returned using echo " .
+                          "rather than using serialize. If that index does not exist or no meta data is " .
+                          "present then the return value is 1.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_meta_get
+       /**
+        * Cli Command arg metaget
+        *
+        * @return array  The arguments for meta get.
+        */
+       public function cli_cmd_arg_meta_get()
+       {
+               return self::phar_args('Fek', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_meta_get
+       /**
+        * Cli Command Run Metaget
+        *
+        * @see $this->args
+        * @see $phar[$x]->hasMetadata()
+        * @see $phar->getMetadata()
+        */
+       public function cli_cmd_run_meta_get()
+       {
+               $phar  = $this->args['f']['val'];
+               $entry = $this->args['e']['val'];
+               $index = $this->args['k']['val'];
+
+               if (isset($entry)) {
+                       if (!$phar[$entry]->hasMetadata()) {
+                               echo "No Metadata\n";
+                               exit(1);
+                       }
+                       echo serialize($phar[$entry]->getMetadata());
+               } else {
+                       if (!$phar->hasMetadata()) {
+                               echo "No Metadata\n";
+                               exit(1);
+                       }
+                       $meta = $phar->getMetadata();
+               }
+
+               if (isset($index)) {
+                       if (isset($index)) {
+                               if (isset($meta[$index])) {
+                                       echo $meta[$index];
+                                       exit(0);
+                               } else {
+                                       echo "No Metadata\n";
+                                       exit(1);
+                               }
+                       } else {
+                               echo serialize($meta);
+                       }
+               }
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_meta_del
+       /**
+        * Cli Command Inf Metadel
+        *
+        * @return string A description of the metadel function
+        */
+       public function cli_cmd_inf_meta_del()
+       {
+               return "Delete meta information of a PHAR entry or a PHAR package.\n" .
+                          "If -k is given then the metadata is expected to be an array " .
+                          "and the given index is being deleted.\n" .
+                          "If something was deleted the return value is 0 otherwise it is 1.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_meta_del
+       /**
+        * CliC ommand Arg Metadelete
+        *
+        * @return array The arguments for metadel
+        */
+       public function cli_cmd_arg_meta_del()
+       {
+               return self::phar_args('Fek', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_meta_del
+       /**
+        * Cli Command Run MetaDel
+        *
+        * @see $phar[$x]->delMetadata()
+        * @see $phar->delMetadata()
+        */
+       public function cli_cmd_run_meta_del()
+       {
+               $phar  = $this->args['f']['val'];
+               $entry = $this->args['e']['val'];
+               $index = $this->args['k']['val'];
+
+               if (isset($entry)) {
+                       if (isset($index)) {
+                               if (!$phar[$entry]->hasMetadata()) {
+                                       exit(1);
+                               }
+                               $meta = $phar[$entry]->getMetadata();
+
+                               // @todo add error message here.
+                               if (!is_array($meta)) {
+                                       exit(1);
+                               }
+
+                               unset($meta[$index]);
+                               $phar[$entry]->setMetadata($meta);
+                       } else {
+                               exit($phar[$entry]->delMetadata() ? 0 : 1);
+                       }
+               } else {
+                       if (isset($index)) {
+                               if (!$phar->hasMetadata()) {
+                                       exit(1);
+                               }
+
+                               $meta = $phar->getMetadata();
+
+                               // @todo Add error message
+                               if (!is_array($meta)) {
+                                       exit(1);
+                               }
+
+                               unset($meta[$index]);
+                               $phar->setMetadata($meta);
+                       } else {
+                               exit($phar->delMetadata() ? 0 : 1);
+                       }
+               }
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_info
+       /**
+        * CLi Command Inf Info
+        *
+        * @return string A description about the info commands.
+        */
+       public function cli_cmd_inf_info()
+       {
+               return "Get information about a PHAR package.\n" .
+                          "By using -k it is possible to return a single value.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_info
+       /**
+        * Cli Command Arg Infos
+        *
+        * @return array The arguments for info command.
+        */
+       public function cli_cmd_arg_info()
+       {
+               return self::phar_args('Fk', 'phar');
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_info
+       /**
+        * Cli Command Run Info
+        *
+        * @param args $args
+        */
+       public function cli_cmd_run_info()
+       {
+               $phar  = $this->args['f']['val'];
+               $index = $this->args['k']['val'];
+
+               $hash  = $phar->getSignature();
+               $infos = array();
+
+               if ($phar->getAlias()) {
+                       $infos['Alias'] = $phar->getAlias();
+               }
+
+               if (!$hash) {
+                       $infos['Hash-type'] = 'NONE';
+               } else {
+                       $infos['Hash-type'] = $hash['hash_type'];
+                       $infos['Hash'] = $hash['hash'];
+               }
+
+               $csize   = 0;
+               $usize   = 0;
+               $count   = 0;
+               $ccount  = 0;
+               $ucount  = 0;
+               $mcount  = 0;
+               $compalg = array('GZ'=>0, 'BZ2'=>0);
+
+               foreach(new RecursiveIteratorIterator($phar) as $ent) {
+                       $count++;
+                       if ($ent->isCompressed()) {
+                               $ccount++;
+                               $csize += $ent->getCompressedSize();
+                               if ($ent->isCompressed(Phar::GZ)) {
+                                       $compalg['GZ']++;
+                               } elseif ($ent->isCompressed(Phar::BZ2)) {
+                                       $compalg['BZ2']++;
+                               }
+                       } else {
+                               $ucount++;
+                               $csize += $ent->getSize();
+                       }
+
+                       $usize += $ent->getSize();
+
+                       if ($ent->hasMetadata()) {
+                               $mcount++;
+                       }
+               }
+
+               $infos['Entries']            = $count;
+               $infos['Uncompressed-files'] = $ucount;
+               $infos['Compressed-files']   = $ccount;
+               $infos['Compressed-gz']      = $compalg['GZ'];
+               $infos['Compressed-bz2']     = $compalg['BZ2'];
+               $infos['Uncompressed-size']  = $usize;
+               $infos['Compressed-size']    = $csize;
+               $infos['Compression-ratio']  = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
+               $infos['Metadata-global']    = $phar->hasMetadata() * 1;
+               $infos['Metadata-files']     = $mcount;
+               $infos['Stub-size']          = strlen($phar->getStub());
+
+               if (isset($index)) {
+                       if (!isset($infos[$index])) {
+                               self::error("Requested value does not exist.\n");
+                       }
+
+                       echo $infos[$index];
+                       exit(0);
+               }
+
+               $l = 0;
+               foreach($infos as $which => $val) {
+                       $l = max(strlen($which), $l);
+               }
+
+               foreach($infos as $which => $val) {
+                       echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
+               }
+       }
+       // }}}
+       // {{{ public function cli_cmd_inf_version
+       /**
+        * CLi Command Inf Version
+        *
+        * @return string A description about the info commands.
+        */
+       public function cli_cmd_inf_version()
+       {
+               return "Get information about the PHAR environment and the tool version.";
+       }
+       // }}}
+       // {{{ public function cli_cmd_arg_version
+       /**
+        * Cli Command Arg Version
+        *
+        * @return array The arguments for version command.
+        */
+       public function cli_cmd_arg_version()
+       {
+               return self::phar_args('', NULL);
+       }
+       // }}}
+       // {{{ public function cli_cmd_run_info
+       /**
+        * Cli Command Run Info
+        *
+        * @param args $args
+        */
+       public function cli_cmd_run_version()
+       {
+               $use_ext = extension_loaded('phar');
+               $version = array(
+                       'PHP Version' => phpversion(),
+                       'phar.phar version' => '$Revision$',
+                       'Phar EXT version' => $use_ext ? phpversion('phar') : 'Not available',
+                       'Phar API version' => Phar::apiVersion(),
+                       'Phar-based phar archives' => true,
+                       'Tar-based phar archives' => $use_ext,
+                       'ZIP-based phar archives' => $use_ext,
+                       'gzip compression' => extension_loaded('zlib'),
+                       'bzip2 compression' => extension_loaded('bz2'),
+                       'supported signatures' => $use_ext ? join(', ', Phar::getSupportedSignatures()) : '',
+                       );
+               $klen = 0;
+               foreach($version as $k => $v)
+               {
+                       $klen = max($klen, strlen($k));
+               }
+               ++$klen;
+               foreach($version as $k => $v) {
+                       if (is_bool($v)) {
+                               $v = $v ? 'enabled' : 'disabled';
+                       }
+                       printf("%-${klen}s  %s\n", $k.':', $v);
+               }
+       }
+       // }}}
 }
 // }}}
 ?>