Function from PEAR::Console_Getopt.
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
190694
private function read_php_argv()
  {
    global $argv;
    if (!is_array($argv))
    {
      if (!@is_array($_SERVER['argv']))
      {
        if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv']))
        {
          throw new pakeException("pakeGetopt: Could not read cmd args (register_argc_argv=Off?).");
        }

        return $GLOBALS['HTTP_SERVER_VARS']['argv'];
      }
      return $_SERVER['argv'];
    }
    return $argv;
  }
891432
public function getOptions()
    {
        foreach ($this->defaultOpts() as $k => $v) {
            if (!isset($this->_options[$k])) {
                $this->_options[$k] = $v;
            }
        }
        // !important see headerCallback() function
        $this->_options[CURLOPT_HEADER] = false;
        return $this->_options;
    }
843590
private function _readTertiaryOPT()
	{
		// offset: 0; size: 2; recVer and recInstance

		// bit: 4-15; mask: 0xFFF0; recInstance
		$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;

		$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
		$recordData = substr($this->_data, $this->_pos + 8, $length);

		// move stream pointer to next record
		$this->_pos += 8 + $length;
	}
82262
public function getFirstArgument()
    {
        foreach ($this->argv as $value) {
            if ($value && '-' === $value[0]) {
                continue;
            }

            return $value;
        }

        return isset($this->definition->getDefaultInputArguments()[0]) ?
            $this->definition->getDefaultInputArguments()[0]->getDefault() : false;
    }
456279
private function getOptions()
    {
        $inputString = (string) $this->input;
        $options     = [];

        // Remove the first two arguments from the array (c/call and the name)
        $content = explode(' ', $inputString, 3);
        if (sizeof($content) > 2 && strpos($inputString, '=') === false) {
            throw new \Exception("Option syntax should contain an equal sign. Ex: --executable=php");
        }
        if (sizeof($content) > 2 && strpos($inputString, '--') === false) {
            throw new \Exception("Option syntax should contain double dashes. Ex: --executable=php");
        }

        // Parse out all of the options
        $pieces = explode('--', $content[2]);
        array_shift($pieces);

        foreach ($pieces as $piece) {
            $piece = trim($piece);
            list($name, $value) = explode('=', $piece, 2);

            if (strpos($value, "'[") === 0 && strpos($value, "]'") === (strlen($value) - 2)) {
                $csv   = trim(str_replace(['[', ']'], '', $value), "'");
                $value = str_getcsv($csv, ',');
            }

            $options[$name] = $value;
        }

        return $options;
    }
1290325
function parse($args = null)
    {
        if ($args === null) {
            $args = array_slice($_SERVER['argv'], 1);
        }

        foreach ($args as $pos => $arg) {
            // reset value
            $value = null;

            if (substr($arg, 0, 1) === '-') {
                if (preg_match('/^(.+)=(.+)$/', $arg, $matches)) {
                    $arg = $matches[1];
                    $value = $matches[2];
                }

                if (!$flag = @$this->flags[$arg]) {
                    throw new ParseException(sprintf('Flag "%s" is not defined.', $arg));
                }

                unset($args[$pos]);

                if ($flag->hasValue) {
                    if (!isset($value)) {
                        $value = $args[$pos + 1];
                        unset($args[$pos + 1]);
                    }
                } else {
                    $value = true;
                }

                if (null !== $flag->callback) {
                    call_user_func_array($flag->callback, array(&$value));
                }

                # Set the reference given as the flag's 'var'.
                $flag->var = $this->parsedFlags[$flag->name] = $value;
            }
        }

        # TODO: Refactor this so this fits into the above foreach
        foreach ($this->flags as $flag) {
            if (!array_key_exists($flag->name, $this->parsedFlags)) {
                $flag->var = $this->parsedFlags[$flag->name] = $flag->defaultValue;
            }
        }

        $this->parsedArgs = $args = array_values($args);

        $pos = 0;

        foreach ($this->args as $arg) {
            if ($arg->required and !isset($args[$pos])) {
                throw new ArgumentException(sprintf(
                    'Missing required argument "%s"', $arg->name
                ));
            }

            if (isset($args[$pos])) {
                if ($arg->vararg) {
                    $value = array_slice($args, $pos);
                    $pos += count($value);
                } else {
                    $value = $args[$pos];
                    $pos++;
                }
            } else {
                $value = $arg->defaultValue;
            }

            $this->parsedNamedArgs[$arg->name] = $value;
        }
    }
210841
public function parseArgv(array $argv = null, $strict = true) {
        if ( ! is_array($argv)) {
            global $argv;
        }

        return $this->parseArgs(array_slice($argv, 1), $strict);
    }
1208455
protected function getParentEnv()
    {
        if (PHP_VERSION_ID >= 70100) {
            return getenv();
        }
        // In PHP <7.1 there isn't a way to read all of the current environment
        // variables. If PHP is running with a variables_order that includes
        // 'e', then $_ENV should be populated.
        if (!empty($_ENV) && stripos(ini_get('variables_order'), 'e') !== false) {
            return $_ENV;
        }

        // If $_ENV is empty, then we can only use a whitelist of all the
        // variables that we might want to use.
        $candidates = [
            'TERM',
            'TERM_SESSION_ID',
            'TMPDIR',
            'SSH_AGENT_PID',
            'SSH_AUTH_SOCK',
            'PATH',
            'LANG',
            'LC_ALL',
            'LC_CTYPE',
            'PAGER',
            'LESS',
        ];
        $variables = [];
        foreach ($candidates as $name) {
            $variables[$name] = getenv($name);
        }

        return array_filter($variables, function ($value) {
            return $value !== false;
        });
    }
433379
function handleswitch($i, $argv)
    {
        $lv = 0;
        $dv = 0.0;
        $sv = $end = $cp = '';
        $j; // int
        $errcnt = 0;
        $cp = strstr($argv[$i], '=');
        if (!$cp) {
            throw new Exception('INTERNAL ERROR: handleswitch passed bad argument, no "=" in arg');
        }
        $argv[$i] = substr($argv[$i], 0, strlen($argv[$i]) - strlen($cp));
        if (!isset(self::$_options[$argv[$i]])) {
            throw new Exception('Command line syntax error: undefined option "' .  $argv[$i] .
                $cp . '"');
        }
        $cp = substr($cp, 1);
        switch (self::$_options[$argv[$i]]['type']) {
        case self::OPT_FLAG:
        case self::OPT_FFLAG:
            throw new Exception('Command line syntax error: option requires an argument "' .
                $argv[$i] . '=' . $cp . '"');
        case self::OPT_DBL:
        case self::OPT_FDBL:
            $dv = (double) $cp;
            break;
        case self::OPT_INT:
        case self::OPT_FINT:
            $lv = (int) $cp;
            break;
        case self::OPT_STR:
        case self::OPT_FSTR:
            $sv = $cp;
            break;
        }
        switch(self::$_options[$argv[$i]]['type']) {
        case self::OPT_FLAG:
        case self::OPT_FFLAG:
            break;
        case self::OPT_DBL:
            $this->{self::$_options[$argv[$i]]['arg']} = $dv;
            break;
        case self::OPT_FDBL:
            $this->{self::$_options[$argv[$i]]['arg']}($dv);
            break;
        case self::OPT_INT:
            $this->{self::$_options[$argv[$i]]['arg']} = $lv;
            break;
        case self::OPT_FINT:
            $this->{self::$_options[$argv[$i]]['arg']}($lv);
            break;
        case self::OPT_STR:
            $this->{self::$_options[$argv[$i]]['arg']} = $sv;
            break;
        case self::OPT_FSTR:
            $this->{self::$_options[$argv[$i]]['arg']}($sv);
            break;
        }
        return 0;
    }
1039965
public function parse() {
        global $argv;

        $options = array();
        $parameters = array();
        $argc = count( $argv );
        $paramCount = count( $this->parameters );
        
        //get parameters
        if( $argc - 1 < $paramCount ) {
            throw new \Exception("The command requires $paramCount parameters.");
        }
        
        //last items are the params
        for( $i = $paramCount - 1; $i >= 0; $i-- ) {
            $this->abstractParameters[$this->parameters[$i]] = $argv[$argc - $i - 1];
        }
        
        //go through each arg
        for( $i = 1; $i < $argc - $paramCount; $i++ ) {
            $arg = $argv[$i];
            
            //cannot start without a switch
            if( !$this->isOption( $arg ) ) {
                throw new \Exception("Invalid argument \"$arg\".");
            }
            
            //check if it's a valid option
            $option = $arg[1];

            if( $this->isParam( $option ) ) {
                //the arg stands on its own, such as -f, not -ffile.txt
                //set next as its value, move $i ahead
                if( $this->isSolitary( $arg ) ) {
                    //last item
                    if( $i == $argc - $paramCount - 1 ) {
                        throw new \Exception("Parameter does not follow the option \"$option\".");
                    }
                    
                    $this->abstractOptions[$option] = $argv[$i+1];
                    $i++;
                } else {
                    $this->abstractOptions[$option] = substr( $arg, 2 );
                }
            } else if( $this->isSwitch( $option ) ) {
                //loop through all switches in the param
                for( $i = 1; $i < strlen( $param ) - 1; $i++ ) {
                    $s = $arg[$i];
                    
                    //not a switch
                    if( !$this->isSwitch( $arg[$i] ) ) {
                        throw new \Exception("An invalid switch \"$s\" was provided.");
                    }
                    
                    $this->abstractOptions[$s] = true;
                }
            }
        }
    }
1184419
private function getCLIGlobalOptions()
    {
        $command = '';
        if (count($this->globalOptions) > 0) {
            foreach ($this->globalOptions as $name => $value) {
                $command .= sprintf(' %s=%s', escapeshellarg($name), escapeshellarg($value));
            }
        }
        return $command;
    }
334218
public function getOption()
    {
        $option = new Option();
        $method = $this->getReflection();

        $comment = $method->getDocComment();
        $parser = new OptionParser();
        $lines = [];
        foreach (preg_split('/\r\n|\n|\r/', $comment) as $line) {
            // /** or */ is skip.
            if (in_array(trim($line), ['/**', '*/', '**/'])) continue;

            $line = preg_replace('/^\s*?\*\s?/', '', $line);

            // options
            if($parser->isSupports($line)) {
                $option->addDefinition($parser->parse($line));
                continue;
            }

            // start char is "@" that is doc comment end signal.
            if (preg_match('/^@\w+/', $line)) continue;

            $lines[] = $line;
        }

        if ($options = $option->getDefinitions()) {
            $lines[] = $parser->formatter($option);
        }

        $option->setDescription(join(PHP_EOL, $lines));

        return $option;
    }
219983
private function getCmd(array $args)
    {
        // get path to console from kernel..
        $consolePath = $this->kernel->getRootDir() . '/console';

        // this code was copied from Symfony\Component\Process\PhpProcess and deserves a cleanup
        $executableFinder = new PhpExecutableFinder();
        if (false === $php = $executableFinder->find()) {
            $php = null;
        }
        if ('\\' !== DIRECTORY_SEPARATOR && null !== $php) {
            // exec is mandatory to deal with sending a signal to the process
            // see https://github.com/symfony/symfony/issues/5030 about prepending
            // command with exec
            $php = 'exec '.$php;
        }

        $cmd = $php.' '.$consolePath.' -n ';

        foreach ($args as $key => $val) {
            if (strlen($key) > 1) {
                $cmd .= ' ' . $key;
            }
            if (strlen($key) > 1 && !is_null($val)) {
                $cmd .= '=';
            }
            if (strlen($val) > 1) {
                $cmd .= escapeshellarg($val);
            }
        }

        return $cmd;
    }
766435
protected function getOptions()
    {
        return [
            ['dry-run', 'r', InputOption::VALUE_NONE, 'Dry run: run process but do not write anything'],
            ['editor', 'e', InputOption::VALUE_NONE, 'Open files which need to be edited at the end of the process'],
            ['force', 'f', InputOption::VALUE_NONE, 'Force files to be rewritten even if there is nothing to do'],
            ['translation', 't', InputOption::VALUE_NONE, 'Try to translate the lemma to the target language'],
            [
                'new-value',
                'l',
                InputOption::VALUE_OPTIONAL,
                'Value of new found lemmas (use %LEMMA for the lemma value or translation). Set it to null to provide translation fallbacks.',
                'TODO: %LEMMA',
            ],
            ['no-backup', 'b', InputOption::VALUE_NONE, 'Do not backup lang file (be careful, I am not a good coder)'],
            ['no-comment', 'c', InputOption::VALUE_NONE, 'Do not add comments in lang files for lemma definition'],
            ['no-date', 'd', InputOption::VALUE_NONE, 'Do not add the date of execution in the lang files'],
            ['no-obsolete', 'o', InputOption::VALUE_NONE, 'Do not write obsolete lemma (obsolete lemma will be removed)'],
            ['output-flat', 'w', InputOption::VALUE_NONE, 'Output arrays are flat (do not use sub-arrays and keep dots in lemma)'],
            ['silent', 's', InputOption::VALUE_NONE, 'Use this option to only return the exit code (use $? in shell to know whether there are missing lemma or nt)'],
            ['php-file-extension', 'x', InputOption::VALUE_OPTIONAL, 'PHP file extension', 'php'],
            ['disable-obsolete-check', 'z', InputOption::VALUE_NONE, 'Use this option to disable check for obsolete lemmas (obsolete lemma will be kept)'],
        ];
    }
622477
function getOpts(input, optdef = null, config = {}){
	
	// Do nothing if given nothing
	if(!input || 0 === input.length)
		return {options: {}, argv: []};
	
	// Avoid modifying original array
	if(Array.isArray(input))
		input = [...input].map(String);
	
	// If called with a string, break it apart into an array
	else if("string" === typeof input)
		input = unstringify(input);
	
	
	// Take a different approach if optdefs aren't specified
	if(null === optdef || "" === optdef || false === optdef)
		return autoOpts(input, config);
	
	
	// Allow "t:h:i:s" style of getopt usage
	if("[object String]" === Object.prototype.toString.call(optdef)){
		const names = optdef.match(/[^\s:]:?/g);
		optdef = {};
		names.forEach(name => {
			optdef[`-${name.replace(/:/, "")}`] = name.length > 1 ? "<arg>" : "";
		});
	}

	// Parse settings that affect runtime option-handling
	const {
		noAliasPropagation,
		noCamelCase,
		noBundling,
		noMixedOrder,
		noUndefined,
		terminator,
		ignoreEquals,
		duplicates = "use-last",
	} = config;
	
	const shortNames = {};
	const longNames = {};
	const result = {argv: [], options: new Object(null)};

	// Define each named option. Throw an error if a duplicate is found.
	for(const name in optdef){
		const option = new Option(name, optdef[name]);
		
		for(const name of option.shortNames){
			if(undefined !== shortNames[name])
				throw new ReferenceError(`Short option "-${name}" already defined`);
			shortNames[`-${name}`] = option;
		}
		
		for(const name of option.longNames){
			if(undefined !== longNames[name])
				throw new ReferenceError(`Long option "--${name}" already defined`);
			longNames[`--${name}`] = option;
		}
	}
	
	// Pointer to the option that's currently picking up arguments
	let currentOption;
	
	
	// Manage duplicated option values
	function resolveDuplicate(option, name, value){
		switch(duplicates){
			
			// Use the first value (or set of values); discard any following duplicates
			case "use-first":
				return result.options[name];
			
			// Use the last value (or set of values); discard any preceding duplicates. Default.
			case "use-last":
			default:
				return result.options[name] = value;
			
			// Use the first/last options; treat any following/preceding duplicates as argv items respectively
			case "limit-first":
			case "limit-last":
				result.argv.push(option.prevMatchedName, ...arrayify(value));
				break;
			
			// Throw an exception
			case "error":
				const error = new TypeError(`Attempting to reassign option "${name}" with value(s) ${JSON.stringify(value)}`);
				error.affectedOption = option;
				error.affectedValue  = value;
				throw error;
			
			// Add parameters of duplicate options to the argument list of the first
			case "append":
				const oldValues = arrayify(result.options[name]);
				const newValues = arrayify(value);
				result.options[name] = oldValues.concat(newValues);
				break;
			
			// Store parameters of duplicated options in a multidimensional array
			case "stack": {
				let oldValues   = result.options[name];
				const newValues = arrayify(value);
				
				// This option hasn't been "stacked" yet
				if(!option.stacked){
					oldValues            = arrayify(oldValues);
					result.options[name] = [oldValues, newValues];
					option.stacked       = true;
				}
				
				// Already "stacked", so just shove the values onto the end of the array
				else result.options[name].push(arrayify(newValues));
				
				break;
			}
			
			// Store each duplicated value in an array using the order they appear
			case "stack-values": {
				let values = result.options[name];
				
				// First time "stacking" this option (nesting its value/s inside an array)
				if(!option.stacked){
					const stack = [];
					for(const value of arrayify(values))
						stack.push([value]);
					values = stack;
					option.stacked = true;
				}
				
				arrayify(value).forEach((v, i) => {
					
					// An array hasn't been created at this index yet,
					// because an earlier option wasn't given enough parameters.
					if(undefined === values[i])
						values[i] = Array(values[0].length - 1);
					
					values[i].push(v);
				});
				
				result.options[name] = values;
				break;
			}
		}
	}
	
	
	// Assign an option's parsed value to the result's `.options` property
	function setValue(option, value){
		
		// Assign the value only to the option name it matched
		if(noAliasPropagation){
			let name = option.lastMatchedName;
			
			// Special alternative:
			// In lieu of using the matched option name, use the first --long-name only
			if("first-only" === noAliasPropagation)
				name = option.longNames[0] || option.shortNames[0];
			
			// camelCase?
			name = formatName(name, noCamelCase);
			
			// This option's already been set before
			if(result.options[name])
				resolveDuplicate(option, name, value);
			
			else result.options[name] = value;
		}
		
		// Copy across every alias this option's recognised by
		else{
			const {names} = option;
			
			for(let name of names){
				
				// Decide whether to camelCase this option name
				name = formatName(name, noCamelCase);
				
				// Ascertain if this option's being duplicated
				if(result.options[name])
					resolveDuplicate(option, name, value);
				
				result.options[name] = value;
			}
		}
	}
	
	
	// Push whatever we've currently collected for this option and reset pointer
	function wrapItUp(){
		let optValue = currentOption.values;
		
		// Don't store solitary values in an array. Store them directly as strings
		if(1 === currentOption.arity && !currentOption.variadic)
			optValue = optValue[0];

		setValue(currentOption, optValue);
		currentOption.values = [];
		currentOption = null;
	}
	
	
	// Reverse the order of an argument list, keeping options and their parameter lists intact
	function flip(input){
		input = input.reverse();
		
		// Flip any options back into the right order
		for(let i = 0, l = input.length; i < l; ++i){
			const arg = input[i];
			const opt = shortNames[arg] || longNames[arg];
			
			if(opt){
				const from    = Math.max(0, i - opt.arity);
				const to      = i + 1;
				const extract = input.slice(from, to).reverse();
				input.splice(from, extract.length, ...extract);
			}
		}
		
		return input;
	}
	
	
	// Tackle bundling. Ensure there's at least one option with a short name to work with.
	const nameKeys = Object.keys(shortNames);
	let bundleMatch, bundlePatterns, niladicArgs;
	
	if(!noBundling && nameKeys.length){
		bundlePatterns  = uniqueStrings(nameKeys.map(n => shortNames[n].bundlePattern)).join("|");
		bundleMatch     = new RegExp(`^-(${bundlePatterns})+`, "g");
		niladicArgs     = uniqueStrings(nameKeys.filter(n => !shortNames[n].arity).map(n => shortNames[n].bundlePattern)).join("|");
		niladicArgs     = new RegExp(`^(-(?:${niladicArgs})+)((?!${bundlePatterns})\\S+)`);
		bundlePatterns  = new RegExp(bundlePatterns, "g");
	}
	
	
	// Is pre-processing of the argument list necessary?
	if(!ignoreEquals || bundleMatch){
		
		// Limit equals-sign expansion to items that begin with recognised option names
		const legalNames = new RegExp(`^(?:${ Object.keys(longNames).join("|") })=`);
		
		for(let i = 0, l = input.length; i < l; ++i){
			let arg = input[i];
			
			// We have bundling in use
			if(bundleMatch){
				bundleMatch.lastIndex = 0;
				
				// Expand bundled option clusters ("-mvl2" -> "-m -v -l 2")
				if(bundleMatch.test(arg)){
					
					// Break off arguments attached to niladic options
					const niladicMatch = arg.match(niladicArgs);
					if(niladicMatch){
						niladicArgs.lastIndex = 0;
						arg = niladicMatch[1];
						input.splice(i + 1, 0, niladicMatch[2]);
						l = input.length;
					}
					
					const segments = [].concat(...arg.match(bundlePatterns).map(m => {
						const option = shortNames[`-${m[0]}`];
						const result = [`-${m[0]}`];
						if(!option.arity) return result;
						result.push(...m.match(new RegExp(option.bundlePattern)).slice(1).filter(i => i));
						return result;
					}));
					input.splice(i, 1, ...segments);
					l =  input.length;
					i += segments.length - 1;
					continue;
				}
			}
			
			// Expand "--option=value" sequences to become "--option value"
			if(legalNames.test(arg)){
				const match = arg.match(/^([^=]+)=(.+)$/);
				input.splice(i, 1, match[1], match[2]);
				l =  input.length;
				i += 1;
			}
		}
	}
	
	
	// If we're handling duplicate options with "limit-last", flip the input order
	if("limit-last" === duplicates)
		input = flip(input);
	
	// Start processing the arguments we were given to handle
	for(let i = 0, l = input.length; i < l; ++i){
		const arg = input[i];
		const opt = shortNames[arg] || longNames[arg];
		
		// This argument matches a recognised option name
		if(opt){
			
			// Record the name given on command-line that matched the option
			opt.lastMatchedName = arg;
			
			// Did we have an existing option that was collecting values?
			if(currentOption) wrapItUp();
			
			
			// Option takes at least one argument
			if(opt.arity)
				currentOption = opt;
			
			// This option takes no arguments, so just assign it a value of "true"
			else setValue(opt, true);
			
			
			// Store an additional back-reference to the current option's name
			opt.prevMatchedName = arg;
		}
		
		else{
			const isTerminator = match(arg, terminator);
			const keepRest = () => result.argv.push(...input.slice(i + 1));
			
			// A previous option is still collecting arguments
			if(currentOption && currentOption.canCollect && !isTerminator)
				currentOption.values.push(arg);
			
			// Not associated with an option
			else{
				currentOption && wrapItUp();
				
				// Terminate option parsing?
				if(isTerminator){
					keepRest();
					break;
				}
				
				// Raise an exception if unrecognised switches are considered an error
				if(noUndefined && /^-./.test(arg)){
					let error = noUndefined;
					
					// Prepare an error object to be thrown in the user's direction
					switch(typeof noUndefined){
						case "function": error = error(arg); break;
						case "boolean":  error = 'Unknown option: "%s"'; // Fall-through
						case "string":   error = new TypeError(error.replace("%s", arg));
					}
					throw error;
				}
				
				result.argv.push(arg);
				
				// Finish processing if mixed-order is disabled
				if(noMixedOrder){
					keepRest();
					break;
				}
			}
		}
	}
	
	
	// Ended abruptly?
	if(currentOption) wrapItUp();
	
	
	// Check if we need to flip the returned .argv array back into the right order again
	if("limit-last" === duplicates)
		result.argv = flip(result.argv);
		
	return result;
}
1152615
public function args_string()
	{
		if ( !isset( $this->args ) || !is_array( $this->args ) )
		{
			return null;
		}
		
		$args = $this->args;
		
		foreach( $args as $key => $arg )
		{
			if ( is_array( $arg ) )
			{
				$args[$key] = 'Array';
			} 
			else 
			{
				$args[$key] = var_export( $arg, true );
			}
		}
		
		return implode( ', ', $args );
	}
39300
public function parseParams($argv)
    {
        if (is_string($argv)) {
            $argv = gplcart_string_explode_whitespace($argv);
        }

        array_shift($argv);

        $out = array();
        for ($i = 0, $j = count($argv); $i < $j; $i++) {

            $key = null;
            $arg = $argv[$i];

            if (substr($arg, 0, 2) === '--') {

                $pos = strpos($arg, '=');

                if ($pos === false) {
                    $key = substr($arg, 2);
                    if ($i + 1 < $j && $argv[$i + 1][0] !== '-') {
                        $value = $argv[$i + 1];
                        $i++;
                    } else {
                        $value = isset($out[$key]) ? $out[$key] : true;
                    }

                    $out[$key] = $value;
                    continue;
                }

                $key = substr($arg, 2, $pos - 2);
                $value = substr($arg, $pos + 1);
                $out[$key] = $value;
                continue;
            }

            if (substr($arg, 0, 1) === '-') {

                if (substr($arg, 2, 1) === '=') {
                    $key = substr($arg, 1, 1);
                    $value = substr($arg, 3);
                    $out[$key] = $value;
                    continue;
                }

                foreach (str_split(substr($arg, 1)) as $char) {
                    $key = $char;
                    $value = isset($out[$key]) ? $out[$key] : true;
                    $out[$key] = $value;
                }

                if ($i + 1 < $j && $argv[$i + 1][0] !== '-') {
                    $out[$key] = $argv[$i + 1];
                    $i++;
                }

                continue;
            }

            $value = $arg;
            $out[] = $value;
        }

        return $out;
    }