[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/phing/types/ -> Commandline.php (source)

   1  <?php
   2  /*
   3   *  $Id: Commandline.php 3076 2006-12-18 08:52:12Z fabien $
   4   *
   5   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   6   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   7   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   8   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   9   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16   *
  17   * This software consists of voluntary contributions made by many individuals
  18   * and is licensed under the LGPL. For more information please see
  19   * <http://phing.info>.
  20   */
  21   
  22  
  23  /**
  24   * Commandline objects help handling command lines specifying processes to
  25   * execute.
  26   *
  27   * The class can be used to define a command line as nested elements or as a
  28   * helper to define a command line by an application.
  29   * <p>
  30   * <code>
  31   * &lt;someelement&gt;<br>
  32   * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
  33   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
  34   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
  35   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
  36   * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
  37   * &lt;/someelement&gt;<br>
  38   * </code>
  39   * The element <code>someelement</code> must provide a method
  40   * <code>createAcommandline</code> which returns an instance of this class.
  41   *
  42   * @author thomas.haas@softwired-inc.com
  43   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
  44   */
  45  class Commandline {
  46  
  47      /**
  48       * @var array CommandlineArguments[]
  49       */
  50      public $arguments = array(); // public so "inner" class can access
  51      
  52      /**
  53       * Full path (if not on %PATH% env var) to executable program.
  54       * @var string
  55       */
  56      public $executable; // public so "inner" class can access
  57  
  58      const DISCLAIMER = "The ' characters around the executable and arguments are not part of the command.";
  59  
  60      public function __construct($to_process = null) {
  61          if ($to_process !== null) {                 
  62              $tmp = $this->translateCommandline($to_process);
  63              if ($tmp) {
  64                  $this->setExecutable(array_shift($tmp)); // removes first el
  65                  foreach($tmp as $arg) { // iterate through remaining elements
  66                      $this->createArgument()->setValue($arg);
  67                  }
  68              }
  69          }    
  70      }
  71  
  72  
  73      /**
  74       * Creates an argument object and adds it to our list of args.
  75       *
  76       * <p>Each commandline object has at most one instance of the
  77       * argument class.</p>
  78       *
  79       * @param boolean $insertAtStart if true, the argument is inserted at the
  80       * beginning of the list of args, otherwise it is appended.
  81       * @return CommandlineArgument
  82       */
  83      public function createArgument($insertAtStart = false) {
  84          $argument = new CommandlineArgument($this);
  85          if ($insertAtStart) {
  86              array_unshift($this->arguments, $argument);
  87          } else {
  88              array_push($this->arguments, $argument);
  89          }
  90          return $argument;
  91      }
  92  
  93      /**
  94       * Sets the executable to run.
  95       */
  96      public function setExecutable($executable) {
  97          if (!$executable) {
  98              return;
  99          }
 100          $this->executable = $executable;
 101          $this->executable = strtr($this->executable, '/', DIRECTORY_SEPARATOR);
 102          $this->executable = strtr($this->executable, '\\', DIRECTORY_SEPARATOR);
 103      }
 104  
 105      public function getExecutable() {
 106          return $this->executable;
 107      }
 108  
 109      public function addArguments($line) {
 110          foreach($line as $arg) {
 111              $this->createArgument()->setValue($arg);
 112          }
 113      }
 114  
 115      /**
 116       * Returns the executable and all defined arguments.
 117       * @return array
 118       */
 119      public function getCommandline() {
 120          $args = $this->getArguments();
 121          if ($this->executable === null) {
 122              return $args;
 123          }
 124          return array_merge(array($this->executable), $args);
 125      }
 126  
 127  
 128      /**
 129       * Returns all arguments defined by <code>addLine</code>,
 130       * <code>addValue</code> or the argument object.
 131       */
 132      public function getArguments() {
 133          $result = array();
 134          foreach($this->arguments as $arg) {
 135              $parts = $arg->getParts();
 136              if ($parts !== null) {                           
 137                  foreach($parts as $part) {
 138                      $result[] = $part;
 139                  }
 140              }
 141          }
 142          return $result;
 143      }
 144  
 145      public function __toString() {
 146          return self::toString($this->getCommandline());
 147      }
 148  
 149      /**
 150       * Put quotes around the given String if necessary.
 151       *
 152       * <p>If the argument doesn't include spaces or quotes, return it
 153       * as is. If it contains double quotes, use single quotes - else
 154       * surround the argument by double quotes.</p>
 155       *
 156       * @exception BuildException if the argument contains both, single
 157       *                           and double quotes.
 158       */
 159      public static function quoteArgument($argument) {
 160          if (strpos($argument, "\"") !== false) {
 161              if (strpos($argument, "'") !== false) {
 162                  throw new BuildException("Can't handle single and double quotes in same argument");
 163              } else {
 164                  return escapeshellarg($argument);
 165              }
 166          } elseif (strpos($argument, "'") !== false || strpos($argument, " ") !== false) {
 167              return escapeshellarg($argument);
 168              //return '\"' . $argument . '\"';
 169          } else {
 170              return $argument;
 171          }
 172      }
 173          
 174      /**
 175       * Quotes the parts of the given array in way that makes them
 176       * usable as command line arguments.
 177       */
 178      public static function toString($lines) {
 179          // empty path return empty string
 180          if (!$lines) {
 181              return "";
 182          }
 183  
 184          // path containing one or more elements
 185          $result = "";
 186          for ($i = 0, $len=count($lines); $i < $len; $i++) {
 187              if ($i > 0) {
 188                  $result .= ' ';
 189              }
 190              $result .= self::quoteArgument($lines[$i]);
 191          }
 192          return $result;
 193      }
 194      
 195      /**
 196       *
 197       * @param string $to_process
 198       * @return array
 199       */
 200      public static function translateCommandline($to_process) {
 201          
 202          if (!$to_process) {
 203              return array();
 204          }
 205              
 206          // parse with a simple finite state machine
 207  
 208          $normal = 0;
 209          $inQuote = 1;
 210          $inDoubleQuote = 2;
 211          
 212          $state = $normal;
 213          $args = array();
 214          $current = "";
 215          $lastTokenHasBeenQuoted = false;
 216          
 217          $tok = strtok($to_process, "");
 218          $tokens = preg_split('/(["\' ])/', $to_process, -1, PREG_SPLIT_DELIM_CAPTURE);
 219          while(($nextTok = array_shift($tokens)) !== null) {
 220              switch ($state) {
 221              case $inQuote:
 222                  if ("'" == $nextTok) {
 223                      $lastTokenHasBeenQuoted = true;
 224                      $state = $normal;
 225                  } else {
 226                      $current .= $nextTok;
 227                  }
 228                  break;
 229              case $inDoubleQuote:
 230                  if ("\"" == $nextTok) {
 231                      $lastTokenHasBeenQuoted = true;
 232                      $state = $normal;
 233                  } else {
 234                      $current .= $nextTok;
 235                  }
 236                  break;
 237              default:
 238                  if ("'" == $nextTok) {
 239                      $state = $inQuote;
 240                  } elseif ("\"" == $nextTok) {
 241                      $state = $inDoubleQuote;
 242                  } elseif (" " == $nextTok) {
 243                      if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
 244                          $args[] = $current;
 245                          $current = "";
 246                      }
 247                  } else {
 248                      $current .= $nextTok;
 249                  }
 250                  $lastTokenHasBeenQuoted = false;
 251                  break;
 252              }
 253          }
 254  
 255          if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
 256              $args[] = $current;
 257          }
 258  
 259          if ($state == $inQuote || $state == $inDoubleQuote) {
 260              throw new BuildException("unbalanced quotes in " . $to_process);
 261          }
 262  
 263          return $args;
 264      }
 265  
 266      /**
 267       * @return int Number of components in current commandline.
 268       */
 269      public function size() {
 270          return count($this->getCommandline());
 271      }
 272  
 273      public function __copy() {
 274          $c = new Commandline();
 275          $c->setExecutable($this->executable);
 276          $c->addArguments($this->getArguments());
 277          return $c;
 278      }
 279  
 280      /**
 281       * Clear out the whole command line.  */
 282      public function clear() {
 283          $this->executable = null;
 284          $this->arguments->removeAllElements();
 285      }
 286  
 287      /**
 288       * Clear out the arguments but leave the executable in place for
 289       * another operation.
 290       */
 291      public function clearArgs() {
 292          $this->arguments = array();
 293      }
 294  
 295      /**
 296       * Return a marker.
 297       *
 298       * <p>This marker can be used to locate a position on the
 299       * commandline - to insert something for example - when all
 300       * parameters have been set.</p>
 301       * @return CommandlineMarker
 302       */
 303      public function createMarker() {
 304          return new CommandlineMarker($this, count($this->arguments));
 305      }
 306  
 307      /**
 308       * Returns a String that describes the command and arguments
 309       * suitable for verbose output before a call to
 310       * <code>Runtime.exec(String[])<code>.
 311       *
 312       * <p>This method assumes that the first entry in the array is the
 313       * executable to run.</p>
 314       * @param array $args CommandlineArgument[] to use
 315       * @return string
 316       */
 317      public function describeCommand($args = null) {
 318         
 319          if ($args === null) {
 320              $args = $this->getCommandline();
 321          }
 322             
 323          if (!$args) {
 324              return "";
 325          }
 326          
 327          $buf = "Executing '";
 328          $buf .= $args[0];
 329          $buf .= "'";
 330          if (count($args) > 0) {
 331              $buf .= " with ";
 332              $buf .= $this->describeArguments($args, 1);
 333          } else {
 334              $buf .= self::DISCLAIMER;
 335          }
 336          return $buf;
 337      }
 338  
 339      /**
 340       * Returns a String that describes the arguments suitable for
 341       * verbose output before a call to
 342       * <code>Runtime.exec(String[])<code>
 343       * @param $args arguments to use (default is to use current class args)
 344       * @param $offset ignore entries before this index
 345       * @return string
 346       */
 347      protected function describeArguments($args = null, $offset = 0) {
 348          if ($args === null) {
 349              $args = $this->getArguments();
 350          }                
 351          
 352          if ($args === null || count($args) <= $offset) {
 353              return "";
 354          }
 355          
 356          $buf = "argument";
 357          if (count($args) > $offset) {
 358              $buf .= "s";
 359          }
 360          $buf .= ":" . Phing::getProperty("line.separator");
 361          for ($i = $offset, $alen=count($args); $i < $alen; $i++) {
 362              $buf .= "'" . $args[$i] . "'" . Phing::getProperty("line.separator");
 363          }
 364          $buf .= self::DISCLAIMER;
 365          return $buf;
 366      }
 367  }
 368  
 369  
 370  /**
 371   * "Inner" class used for nested xml command line definitions.
 372   */
 373  class CommandlineArgument {
 374  
 375      private $parts = array();
 376      private $outer;
 377      
 378      public function __construct(Commandline $outer) {
 379          $this->outer = $outer;
 380      }
 381      
 382      /**
 383       * Sets a single commandline argument.
 384       *
 385       * @param string $value a single commandline argument.
 386       */
 387      public function setValue($value) {
 388          $this->parts = array($value);
 389      }
 390  
 391      /**
 392       * Line to split into several commandline arguments.
 393       *
 394       * @param line line to split into several commandline arguments
 395       */
 396      public function setLine($line) {
 397          if ($line === null) {
 398              return;
 399          }
 400          $this->parts = $this->outer->translateCommandline($line);
 401      }
 402  
 403      /**
 404       * Sets a single commandline argument and treats it like a
 405       * PATH - ensures the right separator for the local platform
 406       * is used.
 407       *
 408       * @param value a single commandline argument.
 409       */
 410      public function setPath($value) {
 411          $this->parts = array( (string) $value );
 412      }
 413  
 414      /**
 415       * Sets a single commandline argument to the absolute filename
 416       * of the given file.
 417       *
 418       * @param value a single commandline argument.
 419       */
 420      public function setFile(PhingFile $value) {
 421          $this->parts = array($value->getAbsolutePath());
 422      }
 423  
 424      /**
 425       * Returns the parts this Argument consists of.
 426       * @return array string[]
 427       */
 428      public function getParts() {
 429          return $this->parts;
 430      }
 431  }
 432  
 433  /**
 434   * Class to keep track of the position of an Argument.
 435   */
 436  // <p>This class is there to support the srcfile and targetfile
 437  // elements of &lt;execon&gt; and &lt;transform&gt; - don't know
 438  // whether there might be additional use cases.</p> --SB
 439  class CommandlineMarker {
 440  
 441      private $position;
 442      private $realPos = -1;
 443      private $outer;
 444      
 445      public function __construct(Comandline $outer, $position) {
 446          $this->outer = $outer;
 447          $this->position = $position;
 448      }
 449  
 450      /**
 451       * Return the number of arguments that preceeded this marker.
 452       *
 453       * <p>The name of the executable - if set - is counted as the
 454       * very first argument.</p>
 455       */
 456      public function getPosition() {
 457          if ($this->realPos == -1) {
 458              $realPos = ($this->outer->executable === null ? 0 : 1);
 459              for ($i = 0; $i < $position; $i++) {
 460                  $arg = $this->arguments[$i];
 461                  $realPos += count($arg->getParts());
 462              }
 463          }
 464          return $this->realPos;
 465      }
 466  }
 467  


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7