⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.78
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Argv
/
Edit File: Option.php
<?php /** * Copyright 2010-2017 Horde LLC (http://www.horde.org/) * * This package is ported from Python's Optik (http://optik.sourceforge.net/). * * See the enclosed file LICENSE for license information (BSD). If you * did not receive this file, see http://www.horde.org/licenses/bsd. * * @author Chuck Hagenbuch <chuck@horde.org> * @author Mike Naberezny <mike@maintainable.com> * @license http://www.horde.org/licenses/bsd BSD * @category Horde * @package Argv */ /** * Defines the Option class and some standard value-checking functions. * * Instance attributes: * shortOpts : [string] * longOpts : [string] * * action : string * type : string * dest : string * default : any * nargs : int * const : any * choices : [string] * callback : function * callbackArgs : (any*) * help : string * metavar : string * * @category Horde * @package Argv * @author Chuck Hagenbuch <chuck@horde.org> * @author Mike Naberezny <mike@maintainable.com> * @copyright 2010-2017 Horde LLC * @license http://www.horde.org/licenses/bsd BSD */ class Horde_Argv_Option { const SUPPRESS_HELP = 'SUPPRESS HELP'; const SUPPRESS_USAGE = 'SUPPRESS USAGE'; /** * Not supplying a default is different from a default of None, * so we need an explicit 'not supplied' value. */ public static $NO_DEFAULT = array('NO', 'DEFAULT'); public static function parseNumber($value) { if (!strlen($value)) { return false; } // Values to check against or compute with. $first = substr($value, 0, 1); $prefix = substr($value, 0, 2); $suffix = substr($value, 2); // Hex if ($prefix == '0x' || $prefix == '0X') { if (strspn($suffix, '0123456789abcdefABCDEF') != strlen($suffix)) { return false; } return hexdec($value); } // Binary if ($prefix == '0b' || $prefix == '0B') { if (strspn($suffix, '01') != strlen($suffix)) { return false; } return bindec($value); } // Octal if ($first == '0') { $suffix = substr($value, 1); if (strspn($suffix, '01234567') != strlen($suffix)) { return false; } return octdec($suffix); } // Base 10 if (!is_numeric($value)) { return false; } return intval($value); } public function checkBuiltin($opt, $value) { switch ($this->type) { case 'int': case 'long': $number = self::parseNumber($value); if ($number === false) { $message = $this->type == 'int' ? Horde_Argv_Translation::t("option %s: invalid integer value: '%s'") : Horde_Argv_Translation::t("option %s: invalid long integer value: '%s'"); throw new Horde_Argv_OptionValueException( sprintf($message, $opt, $value)); } return $number; case 'float': if (!is_numeric($value)) { throw new Horde_Argv_OptionValueException( sprintf(Horde_Argv_Translation::t("option %s: invalid floating-point value: '%s'"), $opt, $value)); } return floatval($value); } } public function checkChoice($opt, $value) { if (in_array($value, $this->choices)) { return $value; } else { $choices = array(); foreach ($this->choices as $choice) { $choices[] = (string)$choice; } $choices = "'" . implode("', '", $choices) . "'"; throw new Horde_Argv_OptionValueException(sprintf( Horde_Argv_Translation::t("option %s: invalid choice: '%s' (choose from %s)"), $opt, $value, $choices)); } } /** * The list of instance attributes that may be set through keyword args to * the constructor. */ public $ATTRS = array( 'action', 'type', 'dest', 'default', 'nargs', 'const', 'choices', 'callback', 'callbackArgs', 'help', 'metavar', ); /** * The set of actions allowed by option parsers. Explicitly listed here so * the constructor can validate its arguments. */ public $ACTIONS = array( 'store', 'store_const', 'store_true', 'store_false', 'append', 'append_const', 'count', 'callback', 'help', 'version', ); /** * The set of actions that involve storing a value somewhere; * also listed just for constructor argument validation. (If * the action is one of these, there must be a destination.) */ public $STORE_ACTIONS = array( 'store', 'store_const', 'store_true', 'store_false', 'append', 'append_const', 'count', ); /** * The set of actions for which it makes sense to supply a value type, * ie. which may consume an argument from the command line. */ public $TYPED_ACTIONS = array( 'store', 'append', 'callback', ); /** * The set of actions which *require* a value type, ie. that always consume * an argument from the command line. */ public $ALWAYS_TYPED_ACTIONS = array('store', 'append'); /** * The set of actions which take a 'const' attribute. */ public $CONST_ACTIONS = array('store_const', 'append_const'); /** * The set of known types for option parsers. * * Again, listed here for constructor argument validation. */ public $TYPES = array('string', 'int', 'long', 'float', 'complex', 'choice'); /** * Dictionary of argument checking functions, which convert and validate * option arguments according to the option type. * * Signature of checking functions is: * * <code> * mixed function(Horde_Argv_Option $option, string $opt, string $value) * </code> * * where * - $option is the Horde_Argv_Option instance calling the checker * - $opt is the actual option seen on the command-line (eg. '-a', '--file') * - $value is the option argument seen on the command-line * * The return value should be in the appropriate PHP type * for $option->type -- eg. an integer if $option->type == 'int'. * * If no checker is defined for a type, arguments will be unchecked and * remain strings. */ public $TYPE_CHECKER = array('int' => 'checkBuiltin', 'long' => 'checkBuiltin', 'float' => 'checkBuiltin', 'complex' => 'checkBuiltin', 'choice' => 'checkChoice', ); /** * A list of unbound method objects. * * They are called by the constructor, in order, after all attributes are * initialized. The list is created and filled in later, after all the * methods are actually defined. (I just put it here because I like to * define and document all class attributes in the same place.) Subclasses * that add another _check_*() method should define their own CHECK_METHODS * list that adds their check method to those from this class. */ public $CHECK_METHODS = array('_checkAction', '_checkType', '_checkChoice', '_checkDest', '_checkConst', '_checkNargs', '_checkCallback', ); // -- Constructor/initialization methods ---------------------------- public $shortOpts = array(); public $longOpts = array(); public $dest; public $default; /** * Constructor. */ public function __construct() { // The last argument to this function is an $attrs hash, if it // is present and an array. All other arguments are $opts. $opts = func_get_args(); $num = func_num_args(); if ($num == 0 || $num == 1 || !is_array($opts[$num - 1])) { $attrs = array(); } else { $attrs = array_pop($opts); } // Set shortOpts, longOpts attrs from 'opts' tuple. // Have to be set now, in case no option strings are supplied. $this->shortOpts = array(); $this->longOpts = array(); $opts = $this->_checkOptStrings($opts); $this->_setOptStrings($opts); // Set all other attrs (action, type, etc.) from 'attrs' dict $this->_setAttrs($attrs); // Check all the attributes we just set. There are lots of // complicated interdependencies, but luckily they can be farmed // out to the _check*() methods listed in CHECK_METHODS -- which // could be handy for subclasses! The one thing these all share // is that they raise OptionError if they discover a problem. foreach ($this->CHECK_METHODS as $checker) { call_user_func(array($this, $checker)); } } protected function _checkOptStrings($opts) { // Filter out None because early versions of Optik had exactly // one short option and one long option, either of which // could be None. $opts = array_filter($opts); if (!$opts) { throw new InvalidArgumentException('at least one option string must be supplied'); } return $opts; } protected function _setOptStrings($opts) { foreach ($opts as &$opt) { $opt = (string)$opt; if (strlen($opt) < 2) { throw new Horde_Argv_OptionException(sprintf("invalid option string '%s': must be at least two characters long", $opt), $this); } elseif (strlen($opt) == 2) { if (!($opt[0] == '-' && $opt[1] != '-')) { throw new Horde_Argv_OptionException(sprintf( "invalid short option string '%s': " . "must be of the form -x, (x any non-dash char)", $opt), $this); } $this->shortOpts[] = $opt; } else { if (!(substr($opt, 0, 2) == '--' && $opt[2] != '-')) { throw new Horde_Argv_OptionException(sprintf( "invalid long option string '%s': " . "must start with --, followed by non-dash", $opt), $this); } $this->longOpts[] = $opt; } } } protected function _setAttrs($attrs) { foreach ($this->ATTRS as $attr) { if (array_key_exists($attr, $attrs)) { $this->$attr = $attrs[$attr]; unset($attrs[$attr]); } else { if ($attr == 'default') { $this->$attr = self::$NO_DEFAULT; } else { $this->$attr = null; } } } if ($attrs) { $attrs = array_keys($attrs); sort($attrs); throw new Horde_Argv_OptionException(sprintf( 'invalid keyword arguments: %s', implode(', ', $attrs)), $this); } } // -- Constructor validation methods -------------------------------- public function _checkAction() { if (is_null($this->action)) { $this->action = 'store'; } elseif (!in_array($this->action, $this->ACTIONS)) { throw new Horde_Argv_OptionException(sprintf("invalid action: '%s'", $this->action), $this); } } public function _checkType() { if (is_null($this->type)) { if (in_array($this->action, $this->ALWAYS_TYPED_ACTIONS)) { if (!is_null($this->choices)) { // The 'choices' attribute implies 'choice' type. $this->type = 'choice'; } else { // No type given? 'string' is the most sensible default. $this->type = 'string'; } } } else { if ($this->type == 'str') { $this->type = 'string'; } if (!in_array($this->type, $this->TYPES)) { throw new Horde_Argv_OptionException(sprintf("invalid option type: '%s'", $this->type), $this); } if (!in_array($this->action, $this->TYPED_ACTIONS)) { throw new Horde_Argv_OptionException(sprintf( "must not supply a type for action '%s'", $this->action), $this); } } } public function _checkChoice() { if ($this->type == 'choice') { if (is_null($this->choices)) { throw new Horde_Argv_OptionException( "must supply a list of choices for type 'choice'", $this); } elseif (!(is_array($this->choices) || $this->choices instanceof Iterator)) { throw new Horde_Argv_OptionException(sprintf( "choices must be a list of strings ('%s' supplied)", gettype($this->choices)), $this); } } elseif (!is_null($this->choices)) { throw new Horde_Argv_OptionException(sprintf( "must not supply choices for type '%s'", $this->type), $this); } } public function _checkDest() { // No destination given, and we need one for this action. The // $this->type check is for callbacks that take a value. $takes_value = (in_array($this->action, $this->STORE_ACTIONS) || !is_null($this->type)); if (is_null($this->dest) && $takes_value) { // Glean a destination from the first long option string, // or from the first short option string if no long options. if ($this->longOpts) { // eg. '--foo-bar' -> 'foo_bar' $this->dest = str_replace('-', '_', substr($this->longOpts[0], 2)); } else { $this->dest = $this->shortOpts[0][1]; } } } public function _checkConst() { if (!in_array($this->action, $this->CONST_ACTIONS) && !is_null($this->const)) { throw new Horde_Argv_OptionException(sprintf( "'const' must not be supplied for action '%s'", $this->action), $this); } } public function _checkNargs() { if (in_array($this->action, $this->TYPED_ACTIONS)) { if (is_null($this->nargs)) { $this->nargs = 1; } } elseif (!is_null($this->nargs)) { throw new Horde_Argv_OptionException(sprintf( "'nargs' must not be supplied for action '%s'", $this->action), $this); } } public function _checkCallback() { if ($this->action == 'callback') { if (!is_callable($this->callback)) { $callback_name = is_array($this->callback) ? is_object($this->callback[0]) ? get_class($this->callback[0] . '#' . $this->callback[1]) : implode('#', $this->callback) : $this->callback; throw new Horde_Argv_OptionException(sprintf( "callback not callable: '%s'", $callback_name), $this); } if (!is_null($this->callbackArgs) && !is_array($this->callbackArgs)) { throw new Horde_Argv_OptionException(sprintf( "callbackArgs, if supplied, must be an array: not '%s'", $this->callbackArgs), $this); } } else { if (!is_null($this->callback)) { $callback_name = is_array($this->callback) ? is_object($this->callback[0]) ? get_class($this->callback[0] . '#' . $this->callback[1]) : implode('#', $this->callback) : $this->callback; throw new Horde_Argv_OptionException(sprintf( "callback supplied ('%s') for non-callback option", $callback_name), $this); } if (!is_null($this->callbackArgs)) { throw new Horde_Argv_OptionException( 'callbackArgs supplied for non-callback option', $this); } } } // -- Miscellaneous methods ----------------------------------------- public function __toString() { return implode('/', array_merge($this->shortOpts, $this->longOpts)); } public function takesValue() { return !is_null($this->type); } public function hasDefault() { return $this->default !== self::$NO_DEFAULT; } public function getOptString() { if ($this->longOpts) { return $this->longOpts[0]; } else { return $this->shortOpts[0]; } } // -- Processing methods -------------------------------------------- public function checkValue($opt, $value) { if (!isset($this->TYPE_CHECKER[$this->type])) { return $value; } $checker = $this->TYPE_CHECKER[$this->type]; return call_user_func(array($this, $checker), $opt, $value); } public function convertValue($opt, $value) { if (!is_null($value)) { if ($this->nargs == 1) { return $this->checkValue($opt, $value); } else { $return = array(); foreach ($value as $v) { $return[] = $this->checkValue($opt, $v); } return $return; } } } public function process($opt, $value, $values, $parser) { // First, convert the value(s) to the right type. Howl if any // value(s) are bogus. $value = $this->convertValue($opt, $value); // And then take whatever action is expected of us. // This is a separate method to make life easier for // subclasses to add new actions. return $this->takeAction( $this->action, $this->dest, $opt, $value, $values, $parser); } public function takeAction($action, $dest, $opt, $value, $values, $parser) { if ($action == 'store') { $values->$dest = $value; } elseif ($action == 'store_const') { $values->$dest = $this->const; } elseif ($action == 'store_true') { $values->$dest = true; } elseif ($action == 'store_false') { $values->$dest = false; } elseif ($action == 'append') { $values->{$dest}[] = $value; } elseif ($action == 'append_const') { $values->{$dest}[] = $this->const; } elseif ($action == 'count') { $values->ensureValue($dest, 0); $values->$dest++; } elseif ($action == 'callback') { call_user_func($this->callback, $this, $opt, $value, $parser, $this->callbackArgs); } elseif ($action == 'help') { $parser->printHelp(); $parser->parserExit(); } elseif ($action == 'version') { $parser->printVersion(); $parser->parserExit(); } else { throw new RuntimeException('unknown action ' . $this->action); } return 1; } }
Simpan