[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> cliopts.php (source)

   1  <?php
   2  /**
   3   * Brutally chopped and modified from http://pear.php.net/package/Console_Getopts
   4   *
   5   * PHP Version 5
   6   *
   7   * Copyright (c) 1997-2004 The PHP Group
   8   *
   9   * LICENSE: This source file is subject to the New BSD license that is
  10   * available through the world-wide-web at the following URI:
  11   * http://www.opensource.org/licenses/bsd-license.php. If you did not receive
  12   * a copy of the New BSD License and are unable to obtain it through the web,
  13   * please send a note to license@php.net so we can mail you a copy immediately.
  14   *
  15   * @category Console
  16   * @package  Console_Getopt
  17   * @author   Andrei Zmievski <andrei@php.net>
  18   * @modified Harry Fuecks hfuecks  gmail.com
  19   * @modified Tanguy Ortolo <tanguy+dokuwiki@ortolo.eu>
  20   * @license  http://www.opensource.org/licenses/bsd-license.php New BSD License
  21   * @version  CVS: $Id$
  22   * @link     http://pear.php.net/package/Console_Getopt
  23   *
  24   */
  25  
  26  //------------------------------------------------------------------------------
  27  /**
  28   * Sets up CLI environment based on SAPI and PHP version
  29   * Helps resolve some issues between the CGI and CLI SAPIs
  30   * as well is inconsistencies between PHP 4.3+ and older versions
  31   */
  32  if (version_compare(phpversion(), '4.3.0', '<') || php_sapi_name() == 'cgi') {
  33      // Handle output buffering
  34      @ob_end_flush();
  35      ob_implicit_flush(true);
  36  
  37      // PHP ini settings
  38      set_time_limit(0);
  39      ini_set('track_errors', "1");
  40      ini_set('html_errors', "0");
  41      ini_set('magic_quotes_runtime', "0");
  42  
  43      // Define stream constants
  44      define('STDIN', fopen('php://stdin', 'r'));
  45      define('STDOUT', fopen('php://stdout', 'w'));
  46      define('STDERR', fopen('php://stderr', 'w'));
  47  
  48      // Close the streams on script termination
  49      register_shutdown_function(
  50          create_function('',
  51          'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;')
  52          );
  53  }
  54  
  55  //------------------------------------------------------------------------------
  56  /**
  57  * Error codes
  58  */
  59  define('DOKU_CLI_OPTS_UNKNOWN_OPT',1); //Unrecognized option
  60  define('DOKU_CLI_OPTS_OPT_ARG_REQUIRED',2); //Option requires argument
  61  define('DOKU_CLI_OPTS_OPT_ARG_DENIED',3); //Option not allowed argument
  62  define('DOKU_CLI_OPTS_OPT_ABIGUOUS',4);//Option abiguous
  63  define('DOKU_CLI_OPTS_ARG_READ',5);//Could not read argv
  64  
  65  //------------------------------------------------------------------------------
  66  /**
  67   * Command-line options parsing class.
  68   *
  69   * @author Andrei Zmievski <andrei@php.net>
  70   *
  71   * @deprecated 2014-05-16
  72   */
  73  class Doku_Cli_Opts {
  74  
  75      /**
  76       * <?php ?>
  77       * @see http://www.sitepoint.com/article/php-command-line-1/3
  78       * @param string $bin_file      executing file name - this MUST be passed the __FILE__ constant
  79       * @param string $short_options short options
  80       * @param array  $long_options  (optional) long options
  81       * @return Doku_Cli_Opts_Container|Doku_Cli_Opts_Error
  82       */
  83      function & getOptions($bin_file, $short_options, $long_options = null) {
  84          $args = Doku_Cli_Opts::readPHPArgv();
  85  
  86          if ( Doku_Cli_Opts::isError($args) ) {
  87              return $args;
  88          }
  89  
  90          // Compatibility between "php extensions.php" and "./extensions.php"
  91          if ( realpath($_SERVER['argv'][0]) == $bin_file ) {
  92              $options = Doku_Cli_Opts::getOpt($args,$short_options,$long_options);
  93          } else {
  94              $options = Doku_Cli_Opts::getOpt2($args,$short_options,$long_options);
  95          }
  96  
  97          if ( Doku_Cli_Opts::isError($options) ) {
  98              return $options;
  99          }
 100  
 101          $container = new Doku_Cli_Opts_Container($options);
 102          return $container;
 103      }
 104  
 105      /**
 106       * Parses the command-line options.
 107       *
 108       * The first parameter to this function should be the list of command-line
 109       * arguments without the leading reference to the running program.
 110       *
 111       * The second parameter is a string of allowed short options. Each of the
 112       * option letters can be followed by a colon ':' to specify that the option
 113       * requires an argument, or a double colon '::' to specify that the option
 114       * takes an optional argument.
 115       *
 116       * The third argument is an optional array of allowed long options. The
 117       * leading '--' should not be included in the option name. Options that
 118       * require an argument should be followed by '=', and options that take an
 119       * option argument should be followed by '=='.
 120       *
 121       * The return value is an array of two elements: the list of parsed
 122       * options and the list of non-option command-line arguments. Each entry in
 123       * the list of parsed options is a pair of elements - the first one
 124       * specifies the option, and the second one specifies the option argument,
 125       * if there was one.
 126       *
 127       * Long and short options can be mixed.
 128       *
 129       * Most of the semantics of this function are based on GNU getopt_long().
 130       *
 131       * @param array  $args          an array of command-line arguments
 132       * @param string $short_options specifies the list of allowed short options
 133       * @param array  $long_options  specifies the list of allowed long options
 134       *
 135       * @return array two-element array containing the list of parsed options and
 136       * the non-option arguments
 137       * @access public
 138       */
 139      function getopt2($args, $short_options, $long_options = null) {
 140          return Doku_Cli_Opts::doGetopt(
 141              2, $args, $short_options, $long_options
 142              );
 143      }
 144  
 145      /**
 146       * This function expects $args to start with the script name (POSIX-style).
 147       * Preserved for backwards compatibility.
 148       *
 149       * @param array  $args          an array of command-line arguments
 150       * @param string $short_options specifies the list of allowed short options
 151       * @param array  $long_options  specifies the list of allowed long options
 152       *
 153       * @see getopt2()
 154       * @return array two-element array containing the list of parsed options and
 155       * the non-option arguments
 156       */
 157      function getopt($args, $short_options, $long_options = null) {
 158          return Doku_Cli_Opts::doGetopt(
 159              1, $args, $short_options, $long_options
 160              );
 161      }
 162  
 163      /**
 164       * The actual implementation of the argument parsing code.
 165       *
 166       * @param int    $version       Version to use
 167       * @param array  $args          an array of command-line arguments
 168       * @param string $short_options specifies the list of allowed short options
 169       * @param array  $long_options  specifies the list of allowed long options
 170       *
 171       * @return array
 172       */
 173      function doGetopt($version, $args, $short_options, $long_options = null) {
 174  
 175          // in case you pass directly readPHPArgv() as the first arg
 176          if (Doku_Cli_Opts::isError($args)) {
 177              return $args;
 178          }
 179          if (empty($args)) {
 180              return array(array(), array());
 181          }
 182          $opts     = array();
 183          $non_opts = array();
 184  
 185          settype($args, 'array');
 186  
 187          if ($long_options && is_array($long_options)) {
 188              sort($long_options);
 189          }
 190  
 191          /*
 192           * Preserve backwards compatibility with callers that relied on
 193           * erroneous POSIX fix.
 194           */
 195          if ($version < 2) {
 196              if (isset($args[0]{0}) && $args[0]{0} != '-') {
 197                  array_shift($args);
 198              }
 199          }
 200  
 201          reset($args);
 202          while (list($i, $arg) = each($args)) {
 203  
 204              /* The special element '--' means explicit end of
 205                 options. Treat the rest of the arguments as non-options
 206                 and end the loop. */
 207              if ($arg == '--') {
 208                  $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
 209                  break;
 210              }
 211  
 212              if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
 213                  $non_opts = array_merge($non_opts, array_slice($args, $i));
 214                  break;
 215              } elseif (strlen($arg) > 1 && $arg{1} == '-') {
 216                  $error = Doku_Cli_Opts::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
 217                  if (Doku_Cli_Opts::isError($error))
 218                      return $error;
 219              } elseif ($arg == '-') {
 220                  // - is stdin
 221                  $non_opts = array_merge($non_opts, array_slice($args, $i));
 222                  break;
 223              } else {
 224                  $error = Doku_Cli_Opts::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
 225                  if (Doku_Cli_Opts::isError($error))
 226                      return $error;
 227              }
 228          }
 229  
 230          return array($opts, $non_opts);
 231      }
 232  
 233      /**
 234       * Parse short option
 235       *
 236       * @param string     $arg           Argument
 237       * @param string     $short_options Available short options
 238       * @param string[][] &$opts
 239       * @param string[]   &$args
 240       *
 241       * @access private
 242       * @return void|Doku_Cli_Opts_Error
 243       */
 244      function _parseShortOption($arg, $short_options, &$opts, &$args) {
 245          $len = strlen($arg);
 246          for ($i = 0; $i < $len; $i++) {
 247              $opt = $arg{$i};
 248              $opt_arg = null;
 249  
 250              /* Try to find the short option in the specifier string. */
 251              if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
 252              {
 253                  return Doku_Cli_Opts::raiseError(
 254                      DOKU_CLI_OPTS_UNKNOWN_OPT,
 255                      "Unrecognized option -- $opt"
 256                      );
 257              }
 258  
 259              if (strlen($spec) > 1 && $spec{1} == ':') {
 260                  if (strlen($spec) > 2 && $spec{2} == ':') {
 261                      if ($i + 1 < strlen($arg)) {
 262                          /* Option takes an optional argument. Use the remainder of
 263                             the arg string if there is anything left. */
 264                          $opts[] = array($opt, substr($arg, $i + 1));
 265                          break;
 266                      }
 267                  } else {
 268                      /* Option requires an argument. Use the remainder of the arg
 269                         string if there is anything left. */
 270                      if ($i + 1 < strlen($arg)) {
 271                          $opts[] = array($opt,  substr($arg, $i + 1));
 272                          break;
 273                      } else if (list(, $opt_arg) = each($args)) {
 274                          /* Else use the next argument. */;
 275                          if (Doku_Cli_Opts::_isShortOpt($opt_arg) || Doku_Cli_Opts::_isLongOpt($opt_arg))
 276                              return Doku_Cli_Opts::raiseError(
 277                                  DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
 278                                  "option requires an argument --$opt"
 279                                  );
 280                      }
 281                      else
 282                          return Doku_Cli_Opts::raiseError(
 283                              DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
 284                              "Option requires an argument -- $opt"
 285                              );
 286                  }
 287              }
 288  
 289              $opts[] = array($opt, $opt_arg);
 290          }
 291      }
 292  
 293      /**
 294       * Checks if an argument is a short option
 295       *
 296       * @param string $arg Argument to check
 297       *
 298       * @access private
 299       * @return bool
 300       */
 301      function _isShortOpt($arg){
 302          return strlen($arg) == 2 && $arg[0] == '-'
 303                 && preg_match('/[a-zA-Z]/', $arg[1]);
 304      }
 305  
 306      /**
 307       * Checks if an argument is a long option
 308       *
 309       * @param string $arg Argument to check
 310       *
 311       * @access private
 312       * @return bool
 313       */
 314      function _isLongOpt($arg){
 315          return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
 316                 preg_match('/[a-zA-Z]+$/', substr($arg, 2));
 317      }
 318  
 319      /**
 320       * Parse long option
 321       *
 322       * @param string     $arg          Argument
 323       * @param string[]   $long_options Available long options
 324       * @param string[][] &$opts
 325       * @param string[]   &$args
 326       *
 327       * @access private
 328       * @return void|Doku_Cli_Opts_Error
 329       */
 330      function _parseLongOption($arg, $long_options, &$opts, &$args) {
 331          @list($opt, $opt_arg) = explode('=', $arg, 2);
 332          $opt_len = strlen($opt);
 333          $opt_cnt = count($long_options);
 334  
 335          for ($i = 0; $i < $opt_cnt; $i++) {
 336              $long_opt  = $long_options[$i];
 337              $opt_start = substr($long_opt, 0, $opt_len);
 338  
 339              $long_opt_name = str_replace('=', '', $long_opt);
 340  
 341              /* Option doesn't match. Go on to the next one. */
 342              if ($opt_start != $opt)
 343                  continue;
 344  
 345              $opt_rest = substr($long_opt, $opt_len);
 346  
 347              /* Check that the options uniquely matches one of the allowed
 348                 options. */
 349              if ($i + 1 < count($long_options)) {
 350                  $next_option_rest = substr($long_options[$i + 1], $opt_len);
 351              } else {
 352                  $next_option_rest = '';
 353              }
 354  
 355              if ($opt_rest != '' && $opt{0} != '=' &&
 356                  $i + 1 < $opt_cnt &&
 357                  $opt == substr($long_options[$i+1], 0, $opt_len) &&
 358                  $next_option_rest != '' &&
 359                  $next_option_rest{0} != '=') {
 360                  return Doku_Cli_Opts::raiseError(
 361                      DOKU_CLI_OPTS_OPT_ABIGUOUS,
 362                      "Option --$opt is ambiguous"
 363                      );
 364              }
 365  
 366              if (substr($long_opt, -1) == '=') {
 367                  if (substr($long_opt, -2) != '==') {
 368                      /* Long option requires an argument.
 369                         Take the next argument if one wasn't specified. */;
 370                      if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
 371                          return Doku_Cli_Opts::raiseError(
 372                              DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
 373                              "Option --$opt requires an argument"
 374                              );
 375                      }
 376  
 377                      if (Doku_Cli_Opts::_isShortOpt($opt_arg)
 378                          || Doku_Cli_Opts::_isLongOpt($opt_arg))
 379                          return Doku_Cli_Opts::raiseError(
 380                              DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
 381                              "Option --$opt requires an argument"
 382                              );
 383                  }
 384              } else if ($opt_arg) {
 385                  return Doku_Cli_Opts::raiseError(
 386                      DOKU_CLI_OPTS_OPT_ARG_DENIED,
 387                      "Option --$opt doesn't allow an argument"
 388                      );
 389              }
 390  
 391              $opts[] = array('--' . $opt, $opt_arg);
 392              return;
 393          }
 394  
 395          return Doku_Cli_Opts::raiseError(
 396              DOKU_CLI_OPTS_UNKNOWN_OPT,
 397              "Unrecognized option --$opt"
 398              );
 399      }
 400  
 401      /**
 402       * Safely read the $argv PHP array across different PHP configurations.
 403       * Will take care on register_globals and register_argc_argv ini directives
 404       *
 405       * @access public
 406       * @return array|Doku_Cli_Opts_Error the $argv PHP array or PEAR error if not registered
 407       */
 408      function readPHPArgv() {
 409          global $argv;
 410          if (!is_array($argv)) {
 411              if (!@is_array($_SERVER['argv'])) {
 412                  if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
 413                      return Doku_Cli_Opts::raiseError(
 414                          DOKU_CLI_OPTS_ARG_READ,
 415                          "Could not read cmd args (register_argc_argv=Off?)"
 416                          );
 417                  }
 418                  return $GLOBALS['HTTP_SERVER_VARS']['argv'];
 419              }
 420              return $_SERVER['argv'];
 421          }
 422          return $argv;
 423      }
 424  
 425      /**
 426       * @param $code
 427       * @param $msg
 428       * @return Doku_Cli_Opts_Error
 429       */
 430      function raiseError($code, $msg) {
 431          return new Doku_Cli_Opts_Error($code, $msg);
 432      }
 433  
 434      /**
 435       * @param $obj
 436       * @return bool
 437       */
 438      function isError($obj) {
 439          return is_a($obj, 'Doku_Cli_Opts_Error');
 440      }
 441  
 442  }
 443  
 444  //------------------------------------------------------------------------------
 445  class Doku_Cli_Opts_Error {
 446  
 447      var $code;
 448      var $msg;
 449  
 450      function __construct($code, $msg) {
 451          $this->code = $code;
 452          $this->msg = $msg;
 453      }
 454  
 455      function getMessage() {
 456          return $this->msg;
 457      }
 458  
 459      function isError() {
 460          return true;
 461      }
 462  
 463  }
 464  
 465  //------------------------------------------------------------------------------
 466  class Doku_Cli_Opts_Container {
 467  
 468      var $options = array();
 469      var $args = array();
 470  
 471      function __construct($options) {
 472          foreach ( $options[0] as $option ) {
 473              if ( false !== ( strpos($option[0], '--') ) ) {
 474                  $opt_name = substr($option[0], 2);
 475              } else {
 476                  $opt_name = $option[0];
 477              }
 478              $this->options[$opt_name] = $option[1];
 479          }
 480  
 481          $this->args = $options[1];
 482      }
 483  
 484      function has($option) {
 485          return array_key_exists($option, $this->options);
 486      }
 487  
 488      function get($option) {
 489          if ( isset($this->options[$option]) ) {
 490              return ( $this->options[$option] ) ;
 491          }
 492      }
 493  
 494      function arg($index) {
 495          if ( isset($this->args[$index]) ) {
 496              return $this->args[$index];
 497          }
 498      }
 499  
 500      function numArgs() {
 501          return count($this->args);
 502      }
 503  
 504      function hasArgs() {
 505          return count($this->args) !== 0;
 506      }
 507  
 508      function isError() {
 509          return false;
 510      }
 511  
 512  }


Generated: Mon Apr 18 03:00:10 2016 Cross-referenced by PHPXref 0.7