[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/tests_runner/src/ -> lmbTestGetopt.class.php (source)

   1  <?php
   2  /*
   3   * Limb PHP Framework
   4   *
   5   * @link http://limb-project.com 
   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
   8   */
   9  
  10  /**
  11   * Class based on PEAR Console_Getopt, it's main goal is to
  12   * remove any external dependencies from TESTS_RUNNER package
  13   */
  14  
  15  // +----------------------------------------------------------------------+
  16  // | PHP Version 5                                                        |
  17  // +----------------------------------------------------------------------+
  18  // | Copyright (c) 1997-2004 The PHP Group                                |
  19  // +----------------------------------------------------------------------+
  20  // | This source file is subject to version 3.0 of the PHP license,       |
  21  // | that is bundled with this package in the file LICENSE, and is        |
  22  // | available through the world-wide-web at the following url:           |
  23  // | http://www.php.net/license/3_0.txt.                                  |
  24  // | If you did not receive a copy of the PHP license and are unable to   |
  25  // | obtain it through the world-wide-web, please send a note to          |
  26  // | license@php.net so we can mail you a copy immediately.               |
  27  // +----------------------------------------------------------------------+
  28  // | Author: Andrei Zmievski <andrei@php.net>                             |
  29  // +----------------------------------------------------------------------+
  30  //
  31  // $Id: Getopt.php,v 1.32 2007/02/18 04:13:07 cellog Exp $
  32  
  33  /**
  34   * Command-line options parsing class.
  35   *
  36   * @author Andrei Zmievski <andrei@php.net>
  37   *
  38   * @package tests_runner
  39   * @version $Id$
  40   */
  41  class lmbTestGetopt {
  42      /**
  43       * Parses the command-line options.
  44       *
  45       * The first parameter to this function should be the list of command-line
  46       * arguments without the leading reference to the running program.
  47       *
  48       * The second parameter is a string of allowed short options. Each of the
  49       * option letters can be followed by a colon ':' to specify that the option
  50       * requires an argument, or a double colon '::' to specify that the option
  51       * takes an optional argument.
  52       *
  53       * The third argument is an optional array of allowed long options. The
  54       * leading '--' should not be included in the option name. Options that
  55       * require an argument should be followed by '=', and options that take an
  56       * option argument should be followed by '=='.
  57       *
  58       * The return value is an array of two elements: the list of parsed
  59       * options and the list of non-option command-line arguments. Each entry in
  60       * the list of parsed options is a pair of elements - the first one
  61       * specifies the option, and the second one specifies the option argument,
  62       * if there was one.
  63       *
  64       * Long and short options can be mixed.
  65       *
  66       * Most of the semantics of this function are based on GNU getopt_long().
  67       *
  68       * @param array  $args           an array of command-line arguments
  69       * @param string $short_options  specifies the list of allowed short options
  70       * @param array  $long_options   specifies the list of allowed long options
  71       *
  72       * @return array two-element array containing the list of parsed options and
  73       * the non-option arguments
  74       *
  75       * @access public
  76       *
  77       */
  78      function getopt2($args, $short_options, $long_options = null)
  79      {
  80          return lmbTestGetopt::doGetopt(2, $args, $short_options, $long_options);
  81      }
  82  
  83      /**
  84       * This function expects $args to start with the script name (POSIX-style).
  85       * Preserved for backwards compatibility.
  86       * @see getopt2()
  87       */
  88      function getopt($args, $short_options, $long_options = null)
  89      {
  90          return lmbTestGetopt::doGetopt(1, $args, $short_options, $long_options);
  91      }
  92  
  93      function defineConstants($argv)
  94      {
  95          for($i=0;$i<sizeof($argv);$i++) {
  96            if(preg_match('~^[A-Z_][A-Z0-9_]+$~', $argv[$i])) {
  97              @define($argv[$i], $argv[$i+1]);
  98            }
  99            elseif(preg_match('~^([A-Z_][A-Z0-9_]+)=(.*)$~', $argv[$i], $m)) {
 100              @define($m[1], $m[2]);
 101            }
 102          }
 103      }
 104  
 105      /**
 106       * The actual implementation of the argument parsing code.
 107       */
 108      function doGetopt($version, $args, $short_options, $long_options = null)
 109      {
 110          if (empty($args)) {
 111              return array(array(), array());
 112          }
 113          $opts     = array();
 114          $non_opts = array();
 115  
 116          settype($args, 'array');
 117  
 118          if ($long_options) {
 119              sort($long_options);
 120          }
 121  
 122          /*
 123           * Preserve backwards compatibility with callers that relied on
 124           * erroneous POSIX fix.
 125           */
 126          if ($version < 2) {
 127              if (isset($args[0]{0}) && $args[0]{0} != '-') {
 128                  array_shift($args);
 129              }
 130          }
 131  
 132          reset($args);
 133          while (list($i, $arg) = each($args)) {
 134  
 135              /* The special element '--' means explicit end of
 136                 options. Treat the rest of the arguments as non-options
 137                 and end the loop. */
 138              if ($arg == '--') {
 139                  $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
 140                  break;
 141              }
 142  
 143              if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
 144                  $non_opts = array_merge($non_opts, array_slice($args, $i));
 145                  break;
 146              } elseif (strlen($arg) > 1 && $arg{1} == '-') {
 147                  lmbTestGetopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
 148              } else {
 149                  lmbTestGetopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
 150              }
 151          }
 152  
 153          return array($opts, $non_opts);
 154      }
 155  
 156      /**
 157       * @access private
 158       *
 159       */
 160      function _parseShortOption($arg, $short_options, &$opts, &$args)
 161      {
 162          for ($i = 0; $i < strlen($arg); $i++) {
 163              $opt = $arg{$i};
 164              $opt_arg = null;
 165  
 166              /* Try to find the short option in the specifier string. */
 167              if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
 168              {
 169                  throw new Exception("unrecognized option -- $opt");
 170              }
 171  
 172              if (strlen($spec) > 1 && $spec{1} == ':') {
 173                  if (strlen($spec) > 2 && $spec{2} == ':') {
 174                      if ($i + 1 < strlen($arg)) {
 175                          /* Option takes an optional argument. Use the remainder of
 176                             the arg string if there is anything left. */
 177                          $opts[] = array($opt, substr($arg, $i + 1));
 178                          break;
 179                      }
 180                  } else {
 181                      /* Option requires an argument. Use the remainder of the arg
 182                         string if there is anything left. */
 183                      if ($i + 1 < strlen($arg)) {
 184                          $opts[] = array($opt,  substr($arg, $i + 1));
 185                          break;
 186                      } else if (list(, $opt_arg) = each($args)) {
 187                          /* Else use the next argument. */;
 188                          if (lmbTestGetopt::_isShortOpt($opt_arg) || lmbTestGetopt::_isLongOpt($opt_arg)) {
 189                               throw new Exception("option requires an argument -- $opt");
 190                          }
 191                      } else {
 192                           throw new Exception("option requires an argument -- $opt");
 193                      }
 194                  }
 195              }
 196  
 197              $opts[] = array($opt, $opt_arg);
 198          }
 199      }
 200  
 201      /**
 202       * @access private
 203       *
 204       */
 205      function _isShortOpt($arg)
 206      {
 207          return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]);
 208      }
 209  
 210      /**
 211       * @access private
 212       *
 213       */
 214      function _isLongOpt($arg)
 215      {
 216          return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
 217              preg_match('/[a-zA-Z]+$/', substr($arg, 2));
 218      }
 219  
 220      /**
 221       * @access private
 222       *
 223       */
 224      function _parseLongOption($arg, $long_options, &$opts, &$args)
 225      {
 226          @list($opt, $opt_arg) = explode('=', $arg, 2);
 227          $opt_len = strlen($opt);
 228  
 229          for ($i = 0; $i < count($long_options); $i++) {
 230              $long_opt  = $long_options[$i];
 231              $opt_start = substr($long_opt, 0, $opt_len);
 232              $long_opt_name = str_replace('=', '', $long_opt);
 233  
 234              /* Option doesn't match. Go on to the next one. */
 235              if ($long_opt_name != $opt) {
 236                  continue;
 237              }
 238  
 239              $opt_rest  = substr($long_opt, $opt_len);
 240  
 241              /* Check that the options uniquely matches one of the allowed
 242                 options. */
 243              $next_option_rest = '';
 244  
 245              if(isset($long_options[$i + 1]))
 246                $next_option_rest = substr($long_options[$i + 1], $opt_len);
 247  
 248              if ($opt_rest != '' && $opt{0} != '=' &&
 249                  $i + 1 < count($long_options) &&
 250                  $opt == substr($long_options[$i+1], 0, $opt_len) &&
 251                  $next_option_rest != '' &&
 252                  $next_option_rest{0} != '=') {
 253                  throw new Exception("option --$opt is ambiguous");
 254              }
 255  
 256              if (substr($long_opt, -1) == '=') {
 257                  if (substr($long_opt, -2) != '==') {
 258                      /* Long option requires an argument.
 259                         Take the next argument if one wasn't specified. */;
 260                      if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
 261                          throw new Exception("option --$opt requires an argument");
 262                      }
 263                  }
 264              } else if ($opt_arg) {
 265                  throw new Exception("option --$opt doesn't allow an argument");
 266              }
 267  
 268              $opts[] = array('--' . $opt, $opt_arg);
 269              return;
 270          }
 271  
 272          throw new Exception("unrecognized option --$opt");
 273      }
 274  
 275      /**
 276      * Safely read the $argv PHP array across different PHP configurations.
 277      * Will take care on register_globals and register_argc_argv ini directives
 278      *
 279      * @access public
 280      * @return mixed the $argv PHP array or PEAR error if not registered
 281      */
 282      function readPHPArgv()
 283      {
 284          global $argv;
 285          if (!is_array($argv)) {
 286              if (!@is_array($_SERVER['argv'])) {
 287                  if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
 288                      throw new Exception("Could not read cmd args (register_argc_argv=Off?)");
 289                  }
 290                  return $GLOBALS['HTTP_SERVER_VARS']['argv'];
 291              }
 292              return $_SERVER['argv'];
 293          }
 294          return $argv;
 295      }
 296  }
 297  
 298  ?>


Generated: Tue Dec 2 03:54:09 2008 Cross-referenced by PHPXref 0.7