Fixing content type ordering when content_type is not defined.
[akelos.git] / vendor / pear / Console / Getargs.php
blobe9b5e6f8f5aa6b8287c80071e4aaecd629bc3ae0
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4 |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 2004 The PHP Group |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to version 3.0 of the PHP license, |
9 // | that is bundled with this package in the file LICENSE, and is |
10 // | available through the world-wide-web at the following url: |
11 // | http://www.php.net/license/3_0.txt. |
12 // | If you did not receive a copy of the PHP license and are unable to |
13 // | obtain it through the world-wide-web, please send a note to |
14 // | license@php.net so we can mail you a copy immediately. |
15 // +----------------------------------------------------------------------+
16 // | Author: Bertrand Mansion <bmansion@mamasam.com> |
17 // +----------------------------------------------------------------------+
19 // $Id: Getargs.php,v 1.18 2005/12/04 16:43:14 wenz Exp $
21 require_once 'PEAR.php';
23 /**#@+
24 * Error Constants
26 /**
27 * Wrong configuration
29 * This error will be TRIGGERed when a configuration error is found,
30 * it will also issue a WARNING.
32 define('CONSOLE_GETARGS_ERROR_CONFIG', -1);
34 /**
35 * User made an error
37 * This error will be RETURNed when a bad parameter
38 * is found in the command line, for example an unknown parameter
39 * or a parameter with an invalid number of options.
41 define('CONSOLE_GETARGS_ERROR_USER', -2);
43 /**
44 * Help text wanted
46 * This error will be RETURNed when the user asked to
47 * see the help by using <kbd>-h</kbd> or <kbd>--help</kbd> in the command line, you can then print
48 * the help ascii art text by using the {@link Console_Getargs::getHelp()} method
50 define('CONSOLE_GETARGS_HELP', -3);
52 /**
53 * Option name for application "parameters"
55 * Parameters are the options an application needs to function.
56 * The two files passed to the diff command would be considered
57 * the parameters. These are different from other options in that
58 * they do not need an option name passed on the command line.
60 define('CONSOLE_GETARGS_PARAMS', 'parameters');
61 /**#@-*/
63 /**
64 * Command-line arguments parsing class
66 * This implementation was freely inspired by a python module called
67 * getargs by Vinod Vijayarajan and a perl CPAN module called
68 * Getopt::Simple by Ron Savage
70 * This class implements a Command Line Parser that your cli applications
71 * can use to parse command line arguments found in $_SERVER['argv'] or a
72 * user defined array.
74 * It gives more flexibility and error checking than Console_Getopt. It also
75 * performs some arguments validation and is capable to return a formatted
76 * help text to the user, based on the configuration it is given.
78 * The class provides the following capabilities:
79 * - Each command line option can take an arbitrary number of arguments.
80 * - Makes the distinction between switches (options without arguments)
81 * and options that require arguments.
82 * - Recognizes 'single-argument-options' and 'default-if-set' options.
83 * - Switches and options with arguments can be interleaved in the command
84 * line.
85 * - You can specify the maximum and minimum number of arguments an option
86 * can take. Use -1 if you don't want to specify an upper bound.
87 * - Specify the default arguments to an option
88 * - Short options can be more than one letter in length.
89 * - A given option may be invoked by multiple names (aliases).
90 * - Understands by default the --help, -h options
91 * - Can return a formatted help text
92 * - Arguments may be specified using the '=' syntax also.
93 * - Short option names may be concatenated (-dvw 100 == -d -v -w 100)
94 * - Can define a default option that will take any arguments added without
95 * an option name
96 * - Can pass in a user defined array of arguments instead of using
97 * $_SERVER['argv']
99 * @todo Implement the parsing of comma delimited arguments
100 * @todo Implement method for turning assocative arrays into command
101 * line arguments (ex. array('d' => true, 'v' => 2) -->
102 * array('-d', '-v', 2))
104 * @author Bertrand Mansion <bmansion@mamasam.com>
105 * @copyright 2004
106 * @license http://www.php.net/license/3_0.txt PHP License 3.0
107 * @version @VER@
108 * @package Console_Getargs
110 class Console_Getargs
113 * Factory creates a new {@link Console_Getargs_Options} object
115 * This method will return a new {@link Console_Getargs_Options}
116 * built using the given configuration options. If the configuration
117 * or the command line options contain errors, the returned object will
118 * in fact be a PEAR_Error explaining the cause of the error.
120 * Factory expects an array as parameter.
121 * The format for this array is:
122 * <pre>
123 * array(
124 * longname => array('short' => Short option name,
125 * 'max' => Maximum arguments for option,
126 * 'min' => Minimum arguments for option,
127 * 'default' => Default option argument,
128 * 'desc' => Option description)
130 * </pre>
132 * If an option can be invoked by more than one name, they have to be defined
133 * by using | as a separator. For example: name1|name2
134 * This works both in long and short names.
136 * max/min are the most/least number of arguments an option accepts.
138 * The 'defaults' field is optional and is used to specify default
139 * arguments to an option. These will be assigned to the option if
140 * it is *not* used in the command line.
141 * Default arguments can be:
142 * - a single value for options that require a single argument,
143 * - an array of values for options with more than one possible arguments.
144 * Default argument(s) are mandatory for 'default-if-set' options.
146 * If max is 0 (option is just a switch), min is ignored.
147 * If max is -1, then the option can have an unlimited number of arguments
148 * greater or equal to min.
150 * If max == min == 1, the option is treated as a single argument option.
152 * If max >= 1 and min == 0, the option is treated as a
153 * 'default-if-set' option. This implies that it will get the default argument
154 * only if the option is used in the command line without any value.
155 * (Note: defaults *must* be specified for 'default-if-set' options)
157 * If the option is not in the command line, the defaults are
158 * *not* applied. If an argument for the option is specified on the command
159 * line, then the given argument is assigned to the option.
160 * Thus:
161 * - a --debug in the command line would cause debug = 'default argument'
162 * - a --debug 2 in the command line would result in debug = 2
163 * if not used in the command line, debug will not be defined.
165 * Example 1.
166 * <code>
167 * require_once 'Console_Getargs.php';
169 * $args =& Console_Getargs::factory($config);
171 * if (PEAR::isError($args)) {
172 * if ($args->getCode() === CONSOLE_GETARGS_ERROR_USER) {
173 * echo Console_Getargs::getHelp($config, null, $args->getMessage())."\n";
174 * } else if ($args->getCode() === CONSOLE_GETARGS_HELP) {
175 * echo Console_Getargs::getHelp($config)."\n";
177 * exit;
180 * echo 'Verbose: '.$args->getValue('verbose')."\n";
181 * if ($args->isDefined('bs')) {
182 * echo 'Block-size: '.(is_array($args->getValue('bs')) ? implode(', ', $args->getValue('bs'))."\n" : $args->getValue('bs')."\n");
183 * } else {
184 * echo "Block-size: undefined\n";
186 * echo 'Files: '.($args->isDefined('file') ? implode(', ', $args->getValue('file'))."\n" : "undefined\n");
187 * if ($args->isDefined('n')) {
188 * echo 'Nodes: '.(is_array($args->getValue('n')) ? implode(', ', $args->getValue('n'))."\n" : $args->getValue('n')."\n");
189 * } else {
190 * echo "Nodes: undefined\n";
192 * echo 'Log: '.$args->getValue('log')."\n";
193 * echo 'Debug: '.($args->isDefined('d') ? "YES\n" : "NO\n");
195 * </code>
197 * If you don't want to require any option name for a set of arguments,
198 * or if you would like any "leftover" arguments assigned by default,
199 * you can create an option named CONSOLE_GETARGS_PARAMS that will
200 * grab any arguments that cannot be assigned to another option. The
201 * rules for CONSOLE_GETARGS_PARAMS are still the same. If you specify
202 * that two values must be passed then two values must be passed. See
203 * the example script for a complete example.
205 * @param array $config associative array with keys being the
206 * options long name
207 * @param array $arguments numeric array of command line arguments
208 * @access public
209 * @return object|PEAR_Error a newly created Console_Getargs_Options
210 * object or a PEAR_Error object on error
212 function &factory($config = array(), $arguments = NULL)
214 // Create the options object.
215 $obj =& new Console_Getargs_Options();
217 // Try to set up the arguments.
218 $err = $obj->init($config, $arguments);
219 if ($err !== true) {
220 return $err;
223 // Try to set up the options.
224 $err = $obj->buildMaps();
225 if ($err !== true) {
226 return $err;
229 // Get the options and arguments from the command line.
230 $err = $obj->parseArgs();
231 if ($err !== true) {
232 return $err;
235 // Set arguments for options that have defaults.
236 $err = $obj->setDefaults();
237 if ($err !== true) {
238 return $err;
241 // All is good.
242 return $obj;
246 * Returns an ascii art version of the help
248 * This method uses the given configuration and parameters
249 * to create and format an help text for the options you defined
250 * in your config parameter. You can supply a header and a footer
251 * as well as the maximum length of a line. If you supplied
252 * descriptions for your options, they will be used as well.
254 * By default, it returns something like this:
255 * <pre>
256 * Usage: myscript.php [-dv --formats] <-fw --filters>
258 * -f --files values(2) Set the source and destination image files.
259 * -w --width=&lt;value&gt; Set the new width of the image.
260 * -d --debug Switch to debug mode.
261 * --formats values(1-3) Set the image destination format. (jpegbig,
262 * jpegsmall)
263 * -fi --filters values(1-...) Set the filters to be applied to the image upon
264 * conversion. The filters will be used in the order
265 * they are set.
266 * -v --verbose (optional)value Set the verbose level. (3)
267 * </pre>
269 * @access public
270 * @param array your args configuration
271 * @param string the header for the help. If it is left null,
272 * a default header will be used, starting by Usage:
273 * @param string the footer for the help. This could be used
274 * to supply a description of the error the user made
275 * @param int help lines max length
276 * @return string the formatted help text
278 function getHelp($config, $helpHeader = null, $helpFooter = '', $maxlength = 78)
280 // Start with an empty help message and build it piece by piece
281 $help = '';
283 // If no user defined header, build the default header.
284 if (!isset($helpHeader)) {
285 // Get the optional, required and "paramter" names for this config.
286 list($optional, $required, $params) = Console_Getargs::getOptionalRequired($config);
287 // Start with the file name.
288 if (isset($_SERVER['SCRIPT_NAME'])) {
289 $filename = basename($_SERVER['SCRIPT_NAME']);
290 } else {
291 $filename = $argv[0];
293 $helpHeader = 'Usage: '. $filename . ' ';
294 // Add the optional arguments and required arguments.
295 $helpHeader.= $optional . ' ' . $required . ' ';
296 // Add any parameters that are needed.
297 $helpHeader.= $params . "\n\n";
300 // Build the list of options and definitions.
301 $i = 0;
302 foreach ($config as $long => $def) {
304 // Break the names up if there is more than one for an option.
305 $shortArr = array();
306 if (isset($def['short'])) {
307 $shortArr = explode('|', $def['short']);
309 $longArr = explode('|', $long);
311 // Column one is the option name displayed as "-short, --long [additional info]"
312 // Add the short option name.
313 $col1[$i] = !empty($shortArr) ? '-'.$shortArr[0].' ' : '';
314 // Add the long option name.
315 $col1[$i] .= '--'.$longArr[0];
317 // Get the min and max to show needed/optional values.
318 $max = $def['max'];
319 $min = isset($def['min']) ? $def['min'] : $max;
321 if ($max === 1 && $min === 1) {
322 // One value required.
323 $col1[$i] .= '=<value>';
324 } else if ($max > 1) {
325 if ($min === $max) {
326 // More than one value needed.
327 $col1[$i] .= ' values('.$max.')';
328 } else if ($min === 0) {
329 // Argument takes optional value(s).
330 $col1[$i] .= ' values(optional)';
331 } else {
332 // Argument takes a range of values.
333 $col1[$i] .= ' values('.$min.'-'.$max.')';
335 } else if ($max === 1 && $min === 0) {
336 // Argument can take at most one value.
337 $col1[$i] .= ' (optional)value';
338 } else if ($max === -1) {
339 // Argument can take unlimited values.
340 if ($min > 0) {
341 $col1[$i] .= ' values('.$min.'-...)';
342 } else {
343 $col1[$i] .= ' (optional)values';
347 // Column two is the description if available.
348 if (isset($def['desc'])) {
349 $col2[$i] = $def['desc'];
350 } else {
351 $col2[$i] = '';
353 // Add the default value(s) if there are any/
354 if (isset($def['default'])) {
355 if (is_array($def['default'])) {
356 $col2[$i] .= ' ('.implode(', ', $def['default']).')';
357 } else {
358 $col2[$i] .= ' ('.$def['default'].')';
361 $i++;
364 // Figure out the maximum length for column one.
365 $arglen = 0;
366 foreach ($col1 as $txt) {
367 $length = strlen($txt);
368 if ($length > $arglen) {
369 $arglen = $length;
373 // The maximum length for each description line.
374 $desclen = $maxlength - $arglen;
375 $padding = str_repeat(' ', $arglen);
376 foreach ($col1 as $k => $txt) {
377 // Wrap the descriptions.
378 if (strlen($col2[$k]) > $desclen) {
379 $desc = wordwrap($col2[$k], $desclen, "\n ".$padding);
380 } else {
381 $desc = $col2[$k];
383 // Push everything together.
384 $help .= str_pad($txt, $arglen).' '.$desc."\n";
387 // Put it all together.
388 return $helpHeader.$help.$helpFooter;
392 * Parse the config array to determine which flags are
393 * optional and which are required.
395 * To make the help header more descriptive, the options
396 * are shown seperated into optional and required flags.
397 * When possible the short flag is used for readability.
398 * Optional items (including "parameters") are surrounded
399 * in square braces ([-vd]). Required flags are surrounded
400 * in angle brackets (<-wf>).
402 * This method may be called statically.
404 * @access public
405 * @param &$config The config array.
406 * @return array
407 * @author Scott Mattocks
408 * @package Console_Getargs
410 function getOptionalRequired(&$config)
412 // Parse the config array and look for optional/required
413 // tags.
414 $optional = '';
415 $optionalHasShort = false;
416 $required = '';
417 $requiredHasShort = false;
419 ksort($config);
420 foreach ($config as $long => $def) {
422 // We only really care about the first option name.
423 $long = explode('|', $long);
424 $long = reset($long);
426 // Treat the "parameters" specially.
427 if ($long == CONSOLE_GETARGS_PARAMS) {
428 continue;
430 // We only really care about the first option name.
431 $def['short'] = explode('|', $def['short']);
432 $def['short'] = reset($def['short']);
434 if (!isset($def['min']) || $def['min'] == 0 || isset($def['default'])) {
435 // This argument is optional.
436 if (isset($def['short']) && strlen($def['short']) == 1) {
437 $optional = $def['short'] . $optional;
438 $optionalHasShort = true;
439 } else {
440 $optional.= ' --' . $long;
442 } else {
443 // This argument is required.
444 if (isset($def['short']) && strlen($def['short']) == 1) {
445 $required = $def['short'] . $required;
446 $requiredHasShort = true;
447 } else {
448 $required.= ' --' . $long;
453 // Check for "parameters" option.
454 $params = '';
455 if (isset($config[CONSOLE_GETARGS_PARAMS])) {
456 for ($i = 1; $i <= max($config[CONSOLE_GETARGS_PARAMS]['max'], $config[CONSOLE_GETARGS_PARAMS]['min']); ++$i) {
457 if ($config[CONSOLE_GETARGS_PARAMS]['max'] == -1 ||
458 ($i > $config[CONSOLE_GETARGS_PARAMS]['min'] &&
459 $i <= $config[CONSOLE_GETARGS_PARAMS]['max']) ||
460 isset($config[CONSOLE_GETARGS_PARAMS]['default'])) {
461 // Parameter is optional.
462 $params.= '[param' . $i .'] ';
463 } else {
464 // Parameter is required.
465 $params.= 'param' . $i . ' ';
469 // Add a leading - if needed.
470 if ($optionalHasShort) {
471 $optional = '-' . $optional;
474 if ($requiredHasShort) {
475 $required = '-' . $required;
478 // Add the extra characters if needed.
479 if (!empty($optional)) {
480 $optional = '[' . $optional . ']';
482 if (!empty($required)) {
483 $required = '<' . $required . '>';
486 return array($optional, $required, $params);
488 } // end class Console_Getargs
491 * This class implements a wrapper to the command line options and arguments.
493 * @author Bertrand Mansion <bmansion@mamasam.com>
494 * @package Console_Getargs
496 class Console_Getargs_Options
500 * Lookup to match short options name with long ones
501 * @var array
502 * @access private
504 var $_shortLong = array();
507 * Lookup to match alias options name with long ones
508 * @var array
509 * @access private
511 var $_aliasLong = array();
514 * Arguments set for the options
515 * @var array
516 * @access private
518 var $_longLong = array();
521 * Configuration set at initialization time
522 * @var array
523 * @access private
525 var $_config = array();
528 * A read/write copy of argv
529 * @var array
530 * @access private
532 var $args = array();
535 * Initializes the Console_Getargs_Options object
536 * @param array configuration options
537 * @access private
538 * @throws CONSOLE_GETARGS_ERROR_CONFIG
539 * @return true|PEAR_Error
541 function init($config, $arguments = NULL)
543 if (is_array($arguments)) {
544 // Use the user defined argument list.
545 $this->args = $arguments;
546 } else {
547 // Command line arguments must be available.
548 if (!isset($_SERVER['argv']) || !is_array($_SERVER['argv'])) {
549 return PEAR::raiseError("Could not read argv", CONSOLE_GETARGS_ERROR_CONFIG,
550 PEAR_ERROR_TRIGGER, E_USER_WARNING, 'Console_Getargs_Options::init()');
552 $this->args = $_SERVER['argv'];
555 // Drop the first argument if it doesn't begin with a '-'.
556 if (isset($this->args[0]{0}) && $this->args[0]{0} != '-') {
557 array_shift($this->args);
559 $this->_config = $config;
560 return true;
564 * Makes the lookup arrays for alias and short name mapping with long names
565 * @access private
566 * @throws CONSOLE_GETARGS_ERROR_CONFIG
567 * @return true|PEAR_Error
569 function buildMaps()
571 foreach($this->_config as $long => $def) {
573 $longArr = explode('|', $long);
574 $longname = $longArr[0];
576 if (count($longArr) > 1) {
577 // The fisrt item in the list is "the option".
578 // The rest are aliases.
579 array_shift($longArr);
580 foreach($longArr as $alias) {
581 // Watch out for duplicate aliases.
582 if (isset($this->_aliasLong[$alias])) {
583 return PEAR::raiseError('Duplicate alias for long option '.$alias, CONSOLE_GETARGS_ERROR_CONFIG,
584 PEAR_ERROR_TRIGGER, E_USER_WARNING, 'Console_Getargs_Options::buildMaps()');
587 $this->_aliasLong[$alias] = $longname;
589 // Add the real option name and defintion.
590 $this->_config[$longname] = $def;
591 // Get rid of the old version (name|alias1|...)
592 unset($this->_config[$long]);
595 // Add the (optional) short option names.
596 if (!empty($def['short'])) {
597 // Short names
598 $shortArr = explode('|', $def['short']);
599 $short = $shortArr[0];
600 if (count($shortArr) > 1) {
601 // The first item is "the option".
602 // The rest are aliases.
603 array_shift($shortArr);
604 foreach ($shortArr as $alias) {
605 // Watch out for duplicate aliases.
606 if (isset($this->_shortLong[$alias])) {
607 return PEAR::raiseError('Duplicate alias for short option '.$alias, CONSOLE_GETARGS_ERROR_CONFIG,
608 PEAR_ERROR_TRIGGER, E_USER_WARNING, 'Console_Getargs_Options::buildMaps()');
610 $this->_shortLong[$alias] = $longname;
613 // Add the real short option name.
614 $this->_shortLong[$short] = $longname;
617 return true;
621 * Parses the given options/arguments one by one
622 * @access private
623 * @throws CONSOLE_GETARGS_HELP
624 * @throws CONSOLE_GETARGS_ERROR_USER
625 * @return true|PEAR_Error
627 function parseArgs()
629 // Go through the options and parse the arguments for each.
630 for ($i = 0, $count = count($this->args); $i < $count; $i++) {
631 $arg = $this->args[$i];
632 if ($arg === '--help' || $arg === '-h') {
633 // Asking for help breaks the loop.
634 return PEAR::raiseError(null, CONSOLE_GETARGS_HELP, PEAR_ERROR_RETURN);
637 if ($arg === '--') {
638 // '--' alone signals the start of "parameters"
639 $err = $this->parseArg(CONSOLE_GETARGS_PARAMS, true, ++$i);
640 } elseif (strlen($arg) > 1 && $arg{0} == '-' && $arg{1} == '-') {
641 // Long name used (--option)
642 $err = $this->parseArg(substr($arg, 2), true, $i);
643 } else if (strlen($arg) > 1 && $arg{0} == '-') {
644 // Short name used (-o)
645 $err = $this->parseArg(substr($arg, 1), false, $i);
646 if ($err === -1) {
647 break;
649 } elseif (isset($this->_config[CONSOLE_GETARGS_PARAMS])) {
650 // No flags at all. Try the parameters option.
651 $tempI = &$i - 1;
652 $err = $this->parseArg(CONSOLE_GETARGS_PARAMS, true, $tempI);
653 } else {
654 $err = PEAR::raiseError('Unknown argument '.$arg,
655 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
656 null, 'Console_Getargs_Options::parseArgs()');
658 if ($err !== true) {
659 return $err;
662 // Check to see if we need to reload the arguments
663 // due to concatenated short names.
664 if (isset($err) && $err === -1) {
665 return $this->parseArgs();
668 return true;
672 * Parses one option/argument
673 * @access private
674 * @throws CONSOLE_GETARGS_ERROR_USER
675 * @return true|PEAR_Error
677 function parseArg($arg, $isLong, &$pos)
679 // If the whole short option isn't in the shortLong array
680 // then break it into a bunch of switches.
681 if (!$isLong && !isset($this->_shortLong[$arg]) && strlen($arg) > 1) {
682 $newArgs = array();
683 for ($i = 0; $i < strlen($arg); $i++) {
684 if (array_key_exists($arg{$i}, $this->_shortLong)) {
685 $newArgs[] = '-' . $arg{$i};
686 } else {
687 $newArgs[] = $arg{$i};
690 // Add the new args to the array.
691 array_splice($this->args, $pos, 1, $newArgs);
693 // Reset the option values.
694 $this->_longLong = array();
696 // Then reparse the arguments.
697 return -1;
700 $opt = '';
701 for ($i = 0; $i < strlen($arg); $i++) {
702 // Build the option name one char at a time looking for a match.
703 $opt .= $arg{$i};
704 if ($isLong === false && isset($this->_shortLong[$opt])) {
705 // Found a match in the short option names.
706 $cmp = $opt;
707 $long = $this->_shortLong[$opt];
708 } elseif ($isLong === true && isset($this->_config[$opt])) {
709 // Found a match in the long option names.
710 $long = $cmp = $opt;
711 } elseif ($isLong === true && isset($this->_aliasLong[$opt])) {
712 // Found a match in the long option names.
713 $long = $this->_aliasLong[$opt];
714 $cmp = $opt;
716 if ($arg{$i} === '=') {
717 // End of the option name when '=' is found.
718 break;
722 // If no option name is found, assume -- was passed.
723 if ($opt == '') {
724 $long = CONSOLE_GETARGS_PARAMS;
727 if (isset($long)) {
728 // A match was found.
729 if (strlen($arg) > strlen($cmp)) {
730 // Seperate the argument from the option.
731 // Ex: php test.php -f=image.png
732 // $cmp = 'f'
733 // $arg = 'f=image.png'
734 $arg = substr($arg, strlen($cmp));
735 // Now $arg = '=image.png'
736 if ($arg{0} === '=') {
737 $arg = substr($arg, 1);
738 // Now $arg = 'image.png'
740 } else {
741 // No argument passed for option.
742 $arg = '';
744 // Set the options value.
745 return $this->setValue($long, $arg, $pos);
747 return PEAR::raiseError('Unknown argument '.$opt,
748 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
749 null, 'Console_Getargs_Options::parseArg()');
753 * Set the option arguments
754 * @access private
755 * @throws CONSOLE_GETARGS_ERROR_CONFIG
756 * @throws CONSOLE_GETARGS_ERROR_USER
757 * @return true|PEAR_Error
759 function setValue($optname, $value, &$pos)
761 if (!isset($this->_config[$optname]['max'])) {
762 // Max must be set for every option even if it is zero or -1.
763 return PEAR::raiseError('No max parameter set for '.$optname,
764 CONSOLE_GETARGS_ERROR_CONFIG, PEAR_ERROR_TRIGGER,
765 E_USER_WARNING, 'Console_Getargs_Options::setValue()');
768 $max = $this->_config[$optname]['max'];
769 $min = isset($this->_config[$optname]['min']) ? $this->_config[$optname]['min']: $max;
771 // A value was passed after the option.
772 if ($value !== '') {
773 // Argument is like -v5
774 if ($min == 1 && $max > 0) {
775 // At least one argument is required for option.
776 $this->updateValue($optname, $value);
777 return true;
779 if ($max === 0) {
780 // Argument passed but not expected.
781 return PEAR::raiseError('Argument '.$optname.' does not take any value',
782 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
783 null, 'Console_Getargs_Options::setValue()');
785 // Not enough arguments passed for this option.
786 return PEAR::raiseError('Argument '.$optname.' expects more than one value',
787 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
788 null, 'Console_Getargs_Options::setValue()');
791 if ($min === 1 && $max === 1) {
792 // Argument requires 1 value
793 // If optname is "parameters" take a step back.
794 if ($optname == CONSOLE_GETARGS_PARAMS) {
795 $pos--;
797 if (isset($this->args[$pos+1]) && $this->isValue($this->args[$pos+1])) {
798 // Set the option value and increment the position.
799 $this->updateValue($optname, $this->args[$pos+1]);
800 $pos++;
801 return true;
803 // What we thought was the argument was really the next option.
804 return PEAR::raiseError('Argument '.$optname.' expects one value',
805 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
806 null, 'Console_Getargs_Options::setValue()');
808 } else if ($max === 0) {
809 // Argument is a switch
810 if (isset($this->args[$pos+1]) && $this->isValue($this->args[$pos+1])) {
811 // What we thought was the next option was really an argument for this option.
812 // First update the value
813 $this->updateValue($optname, true);
814 // Then try to assign values to parameters.
815 if (isset($this->_config[CONSOLE_GETARGS_PARAMS])) {
816 return $this->setValue(CONSOLE_GETARGS_PARAMS, '', ++$pos);
817 } else {
818 return PEAR::raiseError('Argument '.$optname.' does not take any value',
819 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
820 null, 'Console_Getargs_Options::setValue()');
823 // Set the switch to on.
824 $this->updateValue($optname, true);
825 return true;
827 } else if ($max >= 1 && $min === 0) {
828 // Argument has a default-if-set value
829 if (!isset($this->_config[$optname]['default'])) {
830 // A default value MUST be assigned when config is loaded.
831 return PEAR::raiseError('No default value defined for '.$optname,
832 CONSOLE_GETARGS_ERROR_CONFIG, PEAR_ERROR_TRIGGER,
833 E_USER_WARNING, 'Console_Getargs_Options::setValue()');
835 if (is_array($this->_config[$optname]['default'])) {
836 // Default value cannot be an array.
837 return PEAR::raiseError('Default value for '.$optname.' must be scalar',
838 CONSOLE_GETARGS_ERROR_CONFIG, PEAR_ERROR_TRIGGER,
839 E_USER_WARNING, 'Console_Getargs_Options::setValue()');
842 // If optname is "parameters" take a step back.
843 if ($optname == CONSOLE_GETARGS_PARAMS) {
844 $pos--;
847 if (isset($this->args[$pos+1]) && $this->isValue($this->args[$pos+1])) {
848 // Assign the option the value from the command line if there is one.
849 $this->updateValue($optname, $this->args[$pos+1]);
850 $pos++;
851 return true;
853 // Otherwise use the default value.
854 $this->updateValue($optname, $this->_config[$optname]['default']);
855 return true;
858 // Argument takes one or more values
859 $added = 0;
860 // If trying to assign values to parameters, must go back one position.
861 if ($optname == CONSOLE_GETARGS_PARAMS) {
862 $pos = max($pos - 1, -1);
864 for ($i = $pos + 1; $i <= count($this->args); $i++) {
865 $paramFull = $max <= count($this->getValue($optname)) && $max != -1;
866 if (isset($this->args[$i]) && $this->isValue($this->args[$i]) && !$paramFull) {
867 // Add the argument value until the next option is hit.
868 $this->updateValue($optname, $this->args[$i]);
869 $added++;
870 $pos++;
871 // Only keep trying if we haven't filled up yet.
872 // or there is no limit
873 if (($added < $max || $max < 0) && ($max < 0 || !$paramFull)) {
874 continue;
877 if ($min > $added && !$paramFull) {
878 // There aren't enough arguments for this option.
879 return PEAR::raiseError('Argument '.$optname.' expects at least '.$min.(($min > 1) ? ' values' : ' value'),
880 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
881 null, 'Console_Getargs_Options::setValue()');
882 } elseif ($max !== -1 && $paramFull) {
883 // Too many arguments for this option.
884 // Try to add the extra options to parameters.
885 if (isset($this->_config[CONSOLE_GETARGS_PARAMS]) && $optname != CONSOLE_GETARGS_PARAMS) {
886 return $this->setValue(CONSOLE_GETARGS_PARAMS, '', ++$pos);
887 } elseif ($optname == CONSOLE_GETARGS_PARAMS && empty($this->args[$i])) {
888 $pos += $added;
889 break;
890 } else {
891 return PEAR::raiseError('Argument '.$optname.' expects maximum '.$max.' values',
892 CONSOLE_GETARGS_ERROR_USER, PEAR_ERROR_RETURN,
893 null, 'Console_Getargs_Options::setValue()');
896 break;
898 // Everything went well.
899 return true;
903 * Checks whether the given parameter is an argument or an option
904 * @access private
905 * @return boolean
907 function isValue($arg)
909 if ((strlen($arg) > 1 && $arg{0} == '-' && $arg{1} == '-') ||
910 (strlen($arg) > 1 && $arg{0} == '-')) {
911 // The next argument is really an option.
912 return false;
914 return true;
918 * Adds the argument to the option
920 * If the argument for the option is already set,
921 * the option arguments will be changed to an array
922 * @access private
923 * @return void
925 function updateValue($optname, $value)
927 if (isset($this->_longLong[$optname])) {
928 if (is_array($this->_longLong[$optname])) {
929 // Add this value to the list of values for this option.
930 $this->_longLong[$optname][] = $value;
931 } else {
932 // There is already one value set. Turn everything into a list of values.
933 $prevValue = $this->_longLong[$optname];
934 $this->_longLong[$optname] = array($prevValue);
935 $this->_longLong[$optname][] = $value;
937 } else {
938 // This is the first value for this option.
939 $this->_longLong[$optname] = $value;
944 * Sets the option default arguments when necessary
945 * @access private
946 * @return true
948 function setDefaults()
950 foreach ($this->_config as $longname => $def) {
951 // Add the default value only if the default is defined
952 // and the option requires at least one argument.
953 if (isset($def['default']) &&
954 ((isset($def['min']) && $def['min'] !== 0) ||
955 (!isset($def['min']) & isset($def['max']) && $def['max'] !== 0)) &&
956 !isset($this->_longLong[$longname])) {
957 $this->_longLong[$longname] = $def['default'];
960 return true;
964 * Checks whether the given option is defined
966 * An option will be defined if an argument was assigned to it using
967 * the command line options. You can use the short, the long or
968 * an alias name as parameter.
970 * @access public
971 * @param string the name of the option to be checked
972 * @return boolean true if the option is defined
974 function isDefined($optname)
976 $longname = $this->getLongName($optname);
977 if (isset($this->_longLong[$longname])) {
978 return true;
980 return false;
984 * Returns the long version of the given parameter
986 * If the given name is not found, it will return the name that
987 * was given, without further ensuring that the option
988 * actually exists
990 * @access private
991 * @param string the name of the option
992 * @return string long version of the option name
994 function getLongName($optname)
996 if (isset($this->_shortLong[$optname])) {
997 // Short version was passed.
998 $longname = $this->_shortLong[$optname];
999 } else if (isset($this->_aliasLong[$optname])) {
1000 // An alias was passed.
1001 $longname = $this->_aliasLong[$optname];
1002 } else {
1003 // No further validation is done.
1004 $longname = $optname;
1006 return $longname;
1010 * Returns the argument of the given option
1012 * You can use the short, alias or long version of the option name.
1013 * This method will try to find the argument(s) of the given option name.
1014 * If it is not found it will return null. If the arg has more than
1015 * one argument, an array of arguments will be returned.
1017 * @access public
1018 * @param string the name of the option
1019 * @return array|string|null argument(s) associated with the option
1021 function getValue($optname)
1023 if ($this->isDefined($optname)) {
1024 // Option is defined. Return its value
1025 $longname = $this->getLongName($optname);
1026 return $this->_longLong[$longname];
1028 // Option is not defined.
1029 return null;
1033 * Returns all arguments that have been parsed and recognized
1035 * The name of the options are stored in the keys of the array.
1036 * You may choose whether you want to use the long or the short
1037 * option names
1039 * @access public
1040 * @param string option names to use for the keys (long or short)
1041 * @return array values for all options
1043 function getValues($optionNames = 'long')
1045 switch ($optionNames) {
1046 case 'short':
1047 $values = array();
1048 foreach ($this->_shortLong as $short => $long) {
1049 if (isset($this->_longLong[$long])) {
1050 $values[$short] = $this->_longLong[$long];
1053 if (isset($this->_longLong['parameters'])) {
1054 $values['parameters'] = $this->_longLong['parameters'];
1056 return $values;
1057 case 'long':
1058 default:
1059 return $this->_longLong;
1062 } // end class Console_Getargs_Options
1064 * Local variables:
1065 * tab-width: 4
1066 * c-basic-offset: 4
1067 * End: