⚝
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: Parser.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 */ /** * Horde command-line argument parsing package. * * Class attributes: * standardOptionList : [Option] * list of standard options that will be accepted by all instances * of this parser class (intended to be overridden by subclasses). * * Instance attributes: * usage : string * a usage string for your program. Before it is displayed * to the user, "%prog" will be expanded to the name of * your program ($this->prog or os.path.basename(sys.argv[0])). * prog : string * the name of the current program (to override * os.path.basename(sys.argv[0])). * epilog : string * paragraph of help text to print after option help * * optionGroups : [OptionGroup] * list of option groups in this parser (option groups are * irrelevant for parsing the command-line, but very useful * for generating help) * * allowInterspersedArgs : bool = true * if true, positional arguments may be interspersed with options. * Assuming -a and -b each take a single argument, the command-line * -ablah foo bar -bboo baz * will be interpreted the same as * -ablah -bboo -- foo bar baz * If this flag were false, that command line would be interpreted as * -ablah -- foo bar -bboo baz * -- ie. we stop processing options as soon as we see the first * non-option argument. (This is the tradition followed by * Python's getopt module, Perl's Getopt::Std, and other argument- * parsing libraries, but it is generally annoying to users.) * * allowUnknownArgs : bool = false * if true, unrecognized arguments will be auto-created, instead * of throwing a BadOptionException. * * ignoreUnknownArgs : bool = false * if true, unrecognized arguments will be silently skipped, instead of * throwing a BadOptionException. * * rargs : [string] * the argument list currently being parsed. Only set when * parseArgs() is active, and continually trimmed down as * we consume arguments. Mainly there for the benefit of * callback options. * largs : [string] * the list of leftover arguments that we have skipped while * parsing options. If allowInterspersedArgs is false, this * list is always empty. * values : Values * the set of option values currently being accumulated. Only * set when parseArgs() is active. Also mainly for callbacks. * * @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_Parser extends Horde_Argv_OptionContainer { public $standardOptionList = array(); protected $_usage; public $optionGroups = array(); public function __construct($args = array()) { $args = array_merge(array( 'usage' => null, 'optionList' => null, 'optionClass' => 'Horde_Argv_Option', 'version' => null, 'conflictHandler' => "error", 'description' => null, 'formatter' => null, 'addHelpOption' => true, 'prog' => null, 'epilog' => null, 'allowInterspersedArgs' => true, 'allowUnknownArgs' => false, 'ignoreUnknownArgs' => false, ), $args); parent::__construct($args['optionClass'], $args['conflictHandler'], $args['description']); $this->setUsage($args['usage']); $this->prog = $args['prog']; $this->version = $args['version']; $this->allowInterspersedArgs = $args['allowInterspersedArgs']; $this->allowUnknownArgs = $args['allowUnknownArgs']; $this->ignoreUnknownArgs = $args['ignoreUnknownArgs']; if (is_null($args['formatter'])) { $args['formatter'] = new Horde_Argv_IndentedHelpFormatter(); } $this->formatter = $args['formatter']; $this->formatter->setParser($this); $this->epilog = $args['epilog']; // Populate the option list; initial sources are the // standardOptionList class attribute, the 'optionList' // argument, and (if applicable) the _addVersionOption() and // _addHelpOption() methods. $this->_populateOptionList($args['optionList'], $args['addHelpOption']); $this->_initParsingState(); } // -- Private methods ----------------------------------------------- // (used by our OptionContainer's constructor) protected function _createOptionList() { $this->optionList = array(); $this->optionGroups = array(); $this->_createOptionMappings(); } protected function _addHelpOption() { $this->addOption('-h', '--help', array('action' => 'help', 'help' => Horde_Argv_Translation::t("show this help message and exit"))); } protected function _addVersionOption() { $this->addOption('--version', array('action' => 'version', 'help' => Horde_Argv_Translation::t("show program's version number and exit"))); } protected function _populateOptionList($optionList, $add_help = true) { if ($this->standardOptionList) $this->addOptions($this->standardOptionList); if ($optionList) $this->addOptions($optionList); if ($this->version) $this->_addVersionOption(); if ($add_help) $this->_addHelpOption(); } protected function _initParsingState() { // These are set in parseArgs() for the convenience of callbacks. $this->rargs = null; $this->largs = null; $this->values = null; } // -- Simple modifier methods --------------------------------------- public function setUsage($usage) { if (is_null($usage)) $this->_usage = '%prog ' . Horde_Argv_Translation::t("[options]"); elseif ($usage == Horde_Argv_Option::SUPPRESS_USAGE) $this->_usage = null; else $this->_usage = $usage; } public function enableInterspersedArgs() { $this->allowInterspersedArgs = true; } public function disableInterspersedArgs() { $this->allowInterspersedArgs = false; } public function setDefault($dest, $value) { $this->defaults[$dest] = $value; } public function setDefaults($defaults) { $this->defaults = array_merge($this->defaults, $defaults); } protected function _getAllOptions() { $options = $this->optionList; foreach ($this->optionGroups as $group) { $options = array_merge($options, $group->optionList); } return $options; } public function getDefaultValues() { $defaults = $this->defaults; foreach ($this->_getAllOptions() as $option) { $default = isset($defaults[$option->dest]) ? $defaults[$option->dest] : null; if (is_string($default)) { $opt_str = $option->getOptString(); $defaults[$option->dest] = $option->checkValue($opt_str, $default); } } return new Horde_Argv_Values($defaults); } // -- OptionGroup methods ------------------------------------------- public function addOptionGroup() { // XXX lots of overlap with OptionContainer::addOption() $args = func_get_args(); if (count($args) && is_string($args[0])) { $groupFactory = new ReflectionClass('Horde_Argv_OptionGroup'); array_unshift($args, $this); $group = $groupFactory->newInstanceArgs($args); } elseif (count($args) == 1) { $group = $args[0]; if (!$group instanceof Horde_Argv_OptionGroup) throw new InvalidArgumentException("not an OptionGroup instance: " . var_export($group, true)); if ($group->parser !== $this) throw new InvalidArgumentException("invalid OptionGroup (wrong parser)"); } else { throw new InvalidArgumentException('invalid arguments'); } $this->optionGroups[] = $group; $this->defaults = array_merge($this->defaults, $group->defaults); return $group; } public function getOptionGroup($opt_str) { if (isset($this->shortOpt[$opt_str])) { $option = $this->shortOpt[$opt_str]; } elseif (isset($this->longOpt[$opt_str])) { $option = $this->longOpt[$opt_str]; } else { return null; } if ($option->container !== $this) { return $option->container; } return null; } // -- Option-parsing methods ---------------------------------------- protected function _getArgs($args = null) { if (is_null($args)) { $args = $_SERVER['argv']; array_shift($args); return $args; } else { return $args; } } /** * Parse the command-line options found in 'args' (default: * sys.argv[1:]). Any errors result in a call to 'parserError()', which * by default prints the usage message to stderr and calls * exit() with an error message. On success returns a pair * (values, args) where 'values' is an Values instance (with all * your option values) and 'args' is the list of arguments left * over after parsing options. */ public function parseArgs($args = null, $values = null) { $rargs = $this->_getArgs($args); $largs = array(); if (is_null($values)) $values = $this->getDefaultValues(); // Store the halves of the argument list as attributes for the // convenience of callbacks: // rargs // the rest of the command-line (the "r" stands for // "remaining" or "right-hand") // largs // the leftover arguments -- ie. what's left after removing // options and their arguments (the "l" stands for "leftover" // or "left-hand") $this->rargs =& $rargs; $this->largs =& $largs; $this->values = $values; try { $this->_processArgs($largs, $rargs, $values); } catch (Horde_Argv_BadOptionException $e) { $this->parserError($e->getMessage()); } catch (Horde_Argv_OptionValueException $e) { $this->parserError($e->getMessage()); } $args = array_merge($largs, $rargs); return $this->checkValues($values, $args); } /** * Check that the supplied option values and leftover arguments are * valid. Returns the option values and leftover arguments * (possibly adjusted, possibly completely new -- whatever you * like). Default implementation just returns the passed-in * values; subclasses may override as desired. */ public function checkValues($values, $args) { return array($values, $args); } /** * _process_args(largs : [string], * rargs : [string], * values : Values) * * Process command-line arguments and populate 'values', consuming * options and arguments from 'rargs'. If 'allowInterspersedArgs' is * false, stop at the first non-option argument. If true, accumulate any * interspersed non-option arguments in 'largs'. */ protected function _processArgs(&$largs, &$rargs, &$values) { while ($rargs) { $arg = $rargs[0]; // We handle bare "--" explicitly, and bare "-" is handled by the // standard arg handler since the short arg case ensures that the // len of the opt string is greater than 1. if ($arg == '--') { array_shift($rargs); return; } elseif (substr($arg, 0, 2) == '--') { // process a single long option (possibly with value(s)) $this->_processLongOpt($rargs, $values); } elseif (substr($arg, 0, 1) == '-' && strlen($arg) > 1) { // process a cluster of short options (possibly with // value(s) for the last one only) $this->_processShortOpts($rargs, $values); } elseif ($this->allowInterspersedArgs) { $largs[] = $arg; array_shift($rargs); } else { // stop now, leave this arg in rargs return; } } // Say this is the original argument list: // [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] // ^ // (we are about to process arg(i)). // // Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of // [arg0, ..., arg(i-1)] (any options and their arguments will have // been removed from largs). // // The while loop will usually consume 1 or more arguments per pass. // If it consumes 1 (eg. arg is an option that takes no arguments), // then after _process_arg() is done the situation is: // // largs = subset of [arg0, ..., arg(i)] // rargs = [arg(i+1), ..., arg(N-1)] // // If allowInterspersedArgs is false, largs will always be // *empty* -- still a subset of [arg0, ..., arg(i-1)], but // not a very interesting subset! } /** * opt : string) -> string * * Determine which long option string 'opt' matches, ie. which one * it is an unambiguous abbrevation for. Raises BadOptionError if * 'opt' doesn't unambiguously match any long option string. */ protected function _matchLongOpt($opt) { return self::matchAbbrev($opt, $this->longOpt); } /** * (s : string, wordmap : {string : Option}) -> string * * Return the string key in 'wordmap' for which 's' is an unambiguous * abbreviation. If 's' is found to be ambiguous or doesn't match any of * 'words', raise BadOptionError. */ public static function matchAbbrev($s, $wordmap) { // Is there an exact match? if (array_key_exists($s, $wordmap)) { return $s; } // Isolate all words with s as a prefix. $possibilities = array(); foreach (array_keys($wordmap) as $word) { if (strncmp($word, $s, strlen($s)) === 0) { $possibilities[] = $word; } } // No exact match, so there had better be just one possibility. if (count($possibilities) == 1) { return $possibilities[0]; } elseif (!$possibilities) { throw new Horde_Argv_BadOptionException($s); } else { // More than one possible completion: ambiguous prefix. sort($possibilities); throw new Horde_Argv_AmbiguousOptionException($s, $possibilities); } } protected function _processLongOpt(&$rargs, &$values) { $arg = array_shift($rargs); // Value explicitly attached to arg? Pretend it's the next // argument. if (strpos($arg, '=') !== false) { list($opt, $next_arg) = explode('=', $arg, 2); array_unshift($rargs, $next_arg); $had_explicit_value = true; } else { $opt = $arg; $had_explicit_value = false; } try { $opt = $this->_matchLongOpt($opt); $option = $this->longOpt[$opt]; } catch (Horde_Argv_BadOptionException $e) { if ($this->ignoreUnknownArgs) { return; } if ($this->allowUnknownArgs) { $option = $this->addOption($opt, array('default' => true, 'action' => 'append')); } else { throw $e; } } if ($option->takesValue()) { $nargs = $option->nargs; if (count($rargs) < $nargs) { if (!$option->hasDefault()) { if ($nargs == 1) { $this->parserError(sprintf(Horde_Argv_Translation::t("%s option requires an argument"), $opt)); } else { $this->parserError(sprintf(Horde_Argv_Translation::t("%s option requires %d arguments"), $opt, $nargs)); } } } elseif ($nargs == 1) { $value = array_shift($rargs); } else { $value = array_splice($rargs, 0, $nargs); } } elseif ($had_explicit_value) { $this->parserError(sprintf(Horde_Argv_Translation::t("%s option does not take a value"), $opt)); } else { $value = null; } $option->process($opt, $value, $values, $this); } protected function _processShortOpts(&$rargs, &$values) { $arg = array_shift($rargs); $stop = false; $i = 1; for ($c = 1, $c_max = strlen($arg); $c < $c_max; $c++) { $ch = $arg[$c]; $opt = '-' . $ch; $option = isset($this->shortOpt[$opt]) ? $this->shortOpt[$opt] : null; $i++; // we have consumed a character if (!$option) { if ($this->allowUnknownArgs) { $option = $this->addOption($opt, array('default' => true, 'action' => 'append')); } else { throw new Horde_Argv_BadOptionException($opt); } } if ($option->takesValue()) { // Any characters left in arg? Pretend they're the // next arg, and stop consuming characters of arg. if ($i < strlen($arg)) { array_unshift($rargs, substr($arg, $i)); $stop = true; } $nargs = $option->nargs; if (count($rargs) < $nargs) { if (!$option->hasDefault()) { if ($nargs == 1) { $this->parserError(sprintf(Horde_Argv_Translation::t("%s option requires an argument"), $opt)); } else { $this->parserError(sprintf(Horde_Argv_Translation::t("%s option requires %d arguments"), $opt, $nargs)); } } } elseif ($nargs == 1) { $value = array_shift($rargs); } else { $value = array_splice($rargs, 0, $nargs); } } else { // option doesn't take a value $value = null; } $option->process($opt, $value, $values, $this); if ($stop) { break; } } } // -- Feedback methods ---------------------------------------------- public function getProgName() { if (is_null($this->prog)) return basename($_SERVER['argv'][0]); else return $this->prog; } public function expandProgName($s) { return str_replace("%prog", $this->getProgName(), $s); } public function getDescription() { return $this->expandProgName($this->description); } public function parserExit($status = 0, $msg = null) { if ($msg) fwrite(STDERR, $msg); exit($status); } /** * Print a usage message incorporating $msg to stderr and exit. * If you override this in a subclass, it should not return -- it * should either exit or raise an exception. * * @param string $msg */ public function parserError($msg) { $this->printUsage(STDERR); $this->parserExit(2, sprintf("%s: error: %s\n", $this->getProgName(), $msg)); } public function getUsage($formatter = null) { if (is_null($formatter)) $formatter = $this->formatter; if ($this->_usage) return $formatter->formatUsage($this->expandProgName($this->_usage)); else return ''; } /** * (file : file = stdout) * * Print the usage message for the current program ($this->_usage) to * 'file' (default stdout). Any occurence of the string "%prog" in * $this->_usage is replaced with the name of the current program * (basename of sys.argv[0]). Does nothing if $this->_usage is empty * or not defined. */ public function printUsage($file = null) { if (!$this->_usage) return; if (is_null($file)) echo $this->getUsage(); else fwrite($file, $this->getUsage()); } public function getVersion() { if ($this->version) return $this->expandProgName($this->version); else return ''; } /** * file : file = stdout * * Print the version message for this program ($this->version) to * 'file' (default stdout). As with printUsage(), any occurence * of "%prog" in $this->version is replaced by the current program's * name. Does nothing if $this->version is empty or undefined. */ public function printVersion($file = null) { if (!$this->version) return; if (is_null($file)) echo $this->getVersion() . "\n"; else fwrite($file, $this->getVersion() . "\n"); } public function formatOptionHelp($formatter = null) { if (is_null($formatter)) $formatter = $this->formatter; $formatter->storeOptionStrings($this); $result = array(); $result[] = $formatter->formatHeading(Horde_Argv_Translation::t("Options")); $formatter->indent(); if ($this->optionList) { $result[] = parent::formatOptionHelp($formatter); $result[] = "\n"; } foreach ($this->optionGroups as $group) { $result[] = $group->formatHelp($formatter); $result[] = "\n"; } $formatter->dedent(); // Drop the last "\n", or the header if no options or option groups: array_pop($result); return implode('', $result); } public function formatEpilog($formatter) { return $formatter->formatEpilog($this->epilog); } public function formatHelp($formatter = null) { if (is_null($formatter)) $formatter = $this->formatter; $result = array(); if ($this->_usage) $result[] = $this->getUsage($formatter) . "\n"; if ($this->description) $result[] = $this->formatDescription($formatter) . "\n"; $result[] = $this->formatOptionHelp($formatter); $result[] = $this->formatEpilog($formatter); return implode('', $result); } /** * file : file = stdout * * Print an extended help message, listing all options and any * help text provided with them, to 'file' (default stdout). */ public function printHelp($file = null) { if (is_null($file)) echo $this->formatHelp(); else fwrite($file, $this->formatHelp()); } }
Simpan