home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / tmp / Console_Getopt-1.2.3 / Console / Getopt.php
Encoding:
PHP Script  |  2007-06-12  |  10.7 KB  |  291 lines

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