Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/* vim: set expandtab tabstop=4 shiftwidth=4: *//*** PHP Version 5** Copyright (c) 1997-2004 The PHP Group** This source file is subject to version 3.0 of the PHP license,* that is bundled with this package in the file LICENSE, and is* available through the world-wide-web at the following url:* http://www.php.net/license/3_0.txt.* If you did not receive a copy of the PHP license and are unable to* obtain it through the world-wide-web, please send a note to* license@php.net so we can mail you a copy immediately.** @category Console* @package Console_Getopt* @author Andrei Zmievski <andrei@php.net>* @license http://www.php.net/license/3_0.txt PHP 3.0* @version CVS: $Id: Getopt.php 306067 2010-12-08 00:13:31Z dufuz $* @link http://pear.php.net/package/Console_Getopt*/require_once 'PEAR.php';/*** Command-line options parsing class.** @category Console* @package Console_Getopt* @author Andrei Zmievski <andrei@php.net>* @license http://www.php.net/license/3_0.txt PHP 3.0* @link http://pear.php.net/package/Console_Getopt*/class Console_Getopt{/*** Parses the command-line options.** The first parameter to this function should be the list of command-line* arguments without the leading reference to the running program.** The second parameter is a string of allowed short options. Each of the* option letters can be followed by a colon ':' to specify that the option* requires an argument, or a double colon '::' to specify that the option* takes an optional argument.** The third argument is an optional array of allowed long options. The* leading '--' should not be included in the option name. Options that* require an argument should be followed by '=', and options that take an* option argument should be followed by '=='.** The return value is an array of two elements: the list of parsed* options and the list of non-option command-line arguments. Each entry in* the list of parsed options is a pair of elements - the first one* specifies the option, and the second one specifies the option argument,* if there was one.** Long and short options can be mixed.** Most of the semantics of this function are based on GNU getopt_long().** @param array $args an array of command-line arguments* @param string $short_options specifies the list of allowed short options* @param array $long_options specifies the list of allowed long options* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option** @return array two-element array containing the list of parsed options and* the non-option arguments* @access public*/function getopt2($args, $short_options, $long_options = null, $skip_unknown = false){return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown);}/*** This function expects $args to start with the script name (POSIX-style).* Preserved for backwards compatibility.** @param array $args an array of command-line arguments* @param string $short_options specifies the list of allowed short options* @param array $long_options specifies the list of allowed long options** @see getopt2()* @return array two-element array containing the list of parsed options and* the non-option arguments*/function getopt($args, $short_options, $long_options = null, $skip_unknown = false){return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown);}/*** The actual implementation of the argument parsing code.** @param int $version Version to use* @param array $args an array of command-line arguments* @param string $short_options specifies the list of allowed short options* @param array $long_options specifies the list of allowed long options* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option** @return array*/function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false){// in case you pass directly readPHPArgv() as the first argif (PEAR::isError($args)) {return $args;}if (empty($args)) {return array(array(), array());}$non_opts = $opts = array();settype($args, 'array');if ($long_options) {sort($long_options);}/** Preserve backwards compatibility with callers that relied on* erroneous POSIX fix.*/if ($version < 2) {if (isset($args[0]{0}) && $args[0]{0} != '-') {array_shift($args);}}reset($args);while (list($i, $arg) = each($args)) {/* The special element '--' means explicit end ofoptions. Treat the rest of the arguments as non-optionsand end the loop. */if ($arg == '--') {$non_opts = array_merge($non_opts, array_slice($args, $i + 1));break;}if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {$non_opts = array_merge($non_opts, array_slice($args, $i));break;} elseif (strlen($arg) > 1 && $arg{1} == '-') {$error = Console_Getopt::_parseLongOption(substr($arg, 2),$long_options,$opts,$args,$skip_unknown);if (PEAR::isError($error)) {return $error;}} elseif ($arg == '-') {// - is stdin$non_opts = array_merge($non_opts, array_slice($args, $i));break;} else {$error = Console_Getopt::_parseShortOption(substr($arg, 1),$short_options,$opts,$args,$skip_unknown);if (PEAR::isError($error)) {return $error;}}}return array($opts, $non_opts);}/*** Parse short option** @param string $arg Argument* @param string[] $short_options Available short options* @param string[][] &$opts* @param string[] &$args* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option** @access private* @return void*/function _parseShortOption($arg, $short_options, &$opts, &$args, $skip_unknown){for ($i = 0; $i < strlen($arg); $i++) {$opt = $arg{$i};$opt_arg = null;/* Try to find the short option in the specifier string. */if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') {if ($skip_unknown === true) {break;}$msg = "Console_Getopt: unrecognized option -- $opt";return PEAR::raiseError($msg);}if (strlen($spec) > 1 && $spec{1} == ':') {if (strlen($spec) > 2 && $spec{2} == ':') {if ($i + 1 < strlen($arg)) {/* Option takes an optional argument. Use the remainder ofthe arg string if there is anything left. */$opts[] = array($opt, substr($arg, $i + 1));break;}} else {/* Option requires an argument. Use the remainder of the argstring if there is anything left. */if ($i + 1 < strlen($arg)) {$opts[] = array($opt, substr($arg, $i + 1));break;} else if (list(, $opt_arg) = each($args)) {/* Else use the next argument. */;if (Console_Getopt::_isShortOpt($opt_arg)|| Console_Getopt::_isLongOpt($opt_arg)) {$msg = "option requires an argument --$opt";return PEAR::raiseError("Console_Getopt:" . $msg);}} else {$msg = "option requires an argument --$opt";return PEAR::raiseError("Console_Getopt:" . $msg);}}}$opts[] = array($opt, $opt_arg);}}/*** Checks if an argument is a short option** @param string $arg Argument to check** @access private* @return bool*/function _isShortOpt($arg){return strlen($arg) == 2 && $arg[0] == '-'&& preg_match('/[a-zA-Z]/', $arg[1]);}/*** Checks if an argument is a long option** @param string $arg Argument to check** @access private* @return bool*/function _isLongOpt($arg){return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&preg_match('/[a-zA-Z]+$/', substr($arg, 2));}/*** Parse long option** @param string $arg Argument* @param string[] $long_options Available long options* @param string[][] &$opts* @param string[] &$args** @access private* @return void|PEAR_Error*/function _parseLongOption($arg, $long_options, &$opts, &$args, $skip_unknown){@list($opt, $opt_arg) = explode('=', $arg, 2);$opt_len = strlen($opt);for ($i = 0; $i < count($long_options); $i++) {$long_opt = $long_options[$i];$opt_start = substr($long_opt, 0, $opt_len);$long_opt_name = str_replace('=', '', $long_opt);/* Option doesn't match. Go on to the next one. */if ($long_opt_name != $opt) {continue;}$opt_rest = substr($long_opt, $opt_len);/* Check that the options uniquely matches one of the allowedoptions. */if ($i + 1 < count($long_options)) {$next_option_rest = substr($long_options[$i + 1], $opt_len);} else {$next_option_rest = '';}if ($opt_rest != '' && $opt{0} != '=' &&$i + 1 < count($long_options) &&$opt == substr($long_options[$i+1], 0, $opt_len) &&$next_option_rest != '' &&$next_option_rest{0} != '=') {$msg = "Console_Getopt: option --$opt is ambiguous";return PEAR::raiseError($msg);}if (substr($long_opt, -1) == '=') {if (substr($long_opt, -2) != '==') {/* Long option requires an argument.Take the next argument if one wasn't specified. */;if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {$msg = "Console_Getopt: option requires an argument --$opt";return PEAR::raiseError($msg);}if (Console_Getopt::_isShortOpt($opt_arg)|| Console_Getopt::_isLongOpt($opt_arg)) {$msg = "Console_Getopt: option requires an argument --$opt";return PEAR::raiseError($msg);}}} else if ($opt_arg) {$msg = "Console_Getopt: option --$opt doesn't allow an argument";return PEAR::raiseError($msg);}$opts[] = array('--' . $opt, $opt_arg);return;}if ($skip_unknown === true) {return;}return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");}/*** Safely read the $argv PHP array across different PHP configurations.* Will take care on register_globals and register_argc_argv ini directives** @access public* @return mixed the $argv PHP array or PEAR error if not registered*/function readPHPArgv(){global $argv;if (!is_array($argv)) {if (!@is_array($_SERVER['argv'])) {if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {$msg = "Could not read cmd args (register_argc_argv=Off?)";return PEAR::raiseError("Console_Getopt: " . $msg);}return $GLOBALS['HTTP_SERVER_VARS']['argv'];}return $_SERVER['argv'];}return $argv;}}