[ Index ]
 

Code source de PRADO 3.0.6

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

title

Body

[fermer]

/framework/3rdParty/PhpShell/PHP/ -> Shell.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 
   3  
   4  /*
   5  (c) 2006 Jan Kneschke <jan@kneschke.de>
   6  
   7  Permission is hereby granted, free of charge, to any person obtaining a copy of
   8  this software and associated documentation files (the "Software"), to deal in
   9  the Software without restriction, including without limitation the rights to
  10  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  11  of the Software, and to permit persons to whom the Software is furnished to do
  12  so, subject to the following conditions:
  13  
  14  The above copyright notice and this permission notice shall be included in all
  15  copies or substantial portions of the Software.
  16  
  17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23  SOFTWARE.
  24  */
  25  
  26  /**
  27  * A interactive PHP Shell
  28  * 
  29  * The more I work with other languages like python and ruby I like their way how they
  30  * work on problems. While PHP is very forgiving on errors, it is weak on the debugging
  31  * side. It was missing a simple to use interactive shell for years. Python and Ruby have
  32  * their ipython and iruby shell which give you a direct way to interact with the objects.
  33  * No need to write a script and execute it afterwards.
  34  * 
  35  * Starting the Shell:
  36  *
  37  * The package contains a shell wrapper for windows and unix:
  38  * <pre>
  39  * sh>  php-shell.sh
  40  * win> php-shell
  41  * </pre>
  42  * 
  43  * Both are calling the wrapper script <code>php -q php-shell-cmd.php</code>
  44  * 
  45  * Inline Help
  46  *
  47  * <pre>
  48  * PHP-Shell - Version 0.2.0, with readline() support
  49  * (c) 2006, Jan Kneschke <jan@kneschke.de>
  50  * 
  51  * >> use '?' to open the inline help
  52  * 
  53  * >> ?
  54  * "inline help for the PHP-shell
  55  * 
  56  *   >> ?
  57  *     print this help
  58  *   >> ? <topic>
  59  *     get the doccomment for a class, method, property or function
  60  *   >> p <var>
  61  *     execute a verbose print (if implemented)
  62  *   >> quit
  63  *     leave shell
  64  * "
  65  * >> ? PHP_Shell
  66  * </pre>
  67  * Alternatives
  68  * 
  69  * - http://david.acz.org/phpa/
  70  * - http://www.hping.org/phpinteractive/
  71  * - the embedded interactive php-shell: $ php -a 
  72  * 
  73  * @package PHP
  74  */
  75  
  76  /**
  77  * PHP_Shell
  78  *
  79  * a interactive PHP Shell with tab-completion and history
  80  * it can catch FATAL errors before executing the code
  81  *
  82  * Extensions are provided through three side-classes:
  83  *
  84  * - PHP_Shell_Commands
  85  * - PHP_Shell_Options
  86  * - PHP_Shell_Extensions
  87  *
  88  * @package PHP
  89  */
  90  
  91  require_once(dirname(__FILE__)."/Shell/Commands.php");
  92  require_once(dirname(__FILE__)."/Shell/Options.php"); /* for the tab-complete */
  93  
  94  class PHP_Shell {
  95      /** 
  96      * current code-buffer
  97      * @var string
  98      */
  99      protected $code; 
 100  
 101      /** 
 102      * set if readline support is enabled 
 103      * @var bool
 104      */
 105      protected $have_readline; 
 106  
 107      /** 
 108      * current version of the class 
 109      * @var string
 110      */
 111      protected $version = '0.3.1';
 112  
 113      /**
 114      *
 115      */
 116      protected $stdin;
 117  
 118      protected $code_buffer;
 119  
 120      public $has_semicolon=false;
 121  
 122      /**
 123      * init the shell and change if readline support is available
 124      */ 
 125      public function __construct() {
 126          $this->code = '';
 127  
 128          $this->stdin = null;
 129  
 130          $this->have_readline = function_exists('readline');
 131  
 132          if ($this->have_readline) {
 133              readline_completion_function('__shell_readline_complete');
 134          }
 135  
 136          $this->use_readline = true;
 137  
 138          $cmd = PHP_Shell_Commands::getInstance();
 139  
 140          $cmd->registerCommand('#^quit$#', $this, 'cmdQuit', 'quit', 'leaves the shell');
 141          $cmd->registerCommand('#^\?$#', $this, 'cmdHelp', '?', 'show this help');
 142          $cmd->registerCommand('#^\?\s+license$#', $this, 'cmdLicense', '? license', 'show license of the shell');
 143      }
 144  
 145     
 146      /**
 147      * parse the PHP code
 148      *
 149      * we parse before we eval() the code to
 150      * - fetch fatal errors before they come up
 151      * - know about where we have to wait for closing braces
 152      *
 153      * @return int 0 if a executable statement is in the code-buffer, non-zero otherwise
 154      */
 155      public function parse() {
 156          ## remove empty lines
 157          if (trim($this->code) == '') return 1;
 158  
 159          $t = token_get_all('<?php '.$this->code.' ?>');
 160    
 161          $need_semicolon = 1; /* do we need a semicolon to complete the statement ? */
 162          $need_return = 1;    /* can we prepend a return to the eval-string ? */
 163          $open_comment = 0;   /* a open multi-line comment */
 164          $eval = '';          /* code to be eval()'ed later */
 165          $braces = array();   /* to track if we need more closing braces */
 166  
 167          $methods = array();  /* to track duplicate methods in a class declaration */
 168          $ts = array();       /* tokens without whitespaces */
 169  
 170          foreach ($t as $ndx => $token) {
 171              if (is_array($token)) {
 172                  $ignore = 0;
 173        
 174                  switch($token[0]) {
 175                  case T_WHITESPACE:
 176                  case T_OPEN_TAG:
 177                  case T_CLOSE_TAG:
 178                      $ignore = 1;
 179                      break;
 180                  case T_FOREACH:
 181                  case T_DO:
 182                  case T_WHILE:
 183                  case T_FOR:
 184  
 185                  case T_IF:
 186                  case T_RETURN:
 187                      
 188                  case T_CLASS:
 189                  case T_FUNCTION:
 190                  case T_INTERFACE:
 191  
 192                  case T_PRINT:
 193                  case T_ECHO:
 194  
 195                  case T_COMMENT:
 196                  case T_UNSET:
 197  
 198                  case T_INCLUDE:
 199                  case T_REQUIRE:
 200                  case T_INCLUDE_ONCE:
 201                  case T_REQUIRE_ONCE:
 202                  case T_TRY:
 203                  case T_SWITCH:
 204                  case T_DEFAULT:
 205                  case T_CASE:
 206                  case T_BREAK:
 207                  case T_DOC_COMMENT:
 208                      $need_return = 0;
 209                      break;
 210                  case T_EMPTY:
 211                  case T_ISSET:
 212                  case T_EVAL:
 213                  case T_EXIT:
 214  
 215                  case T_VARIABLE:
 216                  case T_STRING:
 217                  case T_NEW:
 218                  case T_EXTENDS:
 219                  case T_IMPLEMENTS:
 220                  case T_OBJECT_OPERATOR:
 221                  case T_DOUBLE_COLON:
 222                  case T_INSTANCEOF:
 223  
 224                  case T_CATCH:
 225                  case T_THROW:
 226  
 227                  case T_ELSE:
 228                  case T_AS:
 229                  case T_LNUMBER:
 230                  case T_DNUMBER:
 231                  case T_CONSTANT_ENCAPSED_STRING:
 232                  case T_ENCAPSED_AND_WHITESPACE:
 233                  case T_CHARACTER:
 234                  case T_ARRAY:
 235                  case T_DOUBLE_ARROW:
 236  
 237                  case T_CONST:
 238                  case T_PUBLIC:
 239                  case T_PROTECTED:
 240                  case T_PRIVATE:
 241                  case T_ABSTRACT:
 242                  case T_STATIC:
 243                  case T_VAR:
 244  
 245                  case T_INC:
 246                  case T_DEC:
 247                  case T_SL:
 248                  case T_SL_EQUAL:
 249                  case T_SR:
 250                  case T_SR_EQUAL:
 251  
 252                  case T_IS_EQUAL:
 253                  case T_IS_IDENTICAL:
 254                  case T_IS_GREATER_OR_EQUAL:
 255                  case T_IS_SMALLER_OR_EQUAL:
 256                      
 257                  case T_BOOLEAN_OR:
 258                  case T_LOGICAL_OR:
 259                  case T_BOOLEAN_AND:
 260                  case T_LOGICAL_AND:
 261                  case T_LOGICAL_XOR:
 262                  case T_MINUS_EQUAL:
 263                  case T_PLUS_EQUAL:
 264                  case T_MUL_EQUAL:
 265                  case T_DIV_EQUAL:
 266                  case T_MOD_EQUAL:
 267                  case T_XOR_EQUAL:
 268                  case T_AND_EQUAL:
 269                  case T_OR_EQUAL:
 270  
 271                  case T_FUNC_C:
 272                  case T_CLASS_C:
 273                  case T_LINE:
 274                  case T_FILE:
 275  
 276                  case T_BOOL_CAST:
 277                  case T_INT_CAST:
 278                  case T_STRING_CAST:
 279  
 280                      /* just go on */
 281                      break;
 282                  default:
 283                      /* debug unknown tags*/
 284                      error_log(sprintf("unknown tag: %d (%s): %s".PHP_EOL, $token[0], token_name($token[0]), $token[1]));
 285                      
 286                      break;
 287                  }
 288                  if (!$ignore) {
 289                      $eval .= $token[1]." ";
 290                      $ts[] = array("token" => $token[0], "value" => $token[1]);
 291                  }
 292              } else {
 293                  $ts[] = array("token" => $token, "value" => '');
 294  
 295                  $last = count($ts) - 1;
 296  
 297                  switch ($token) {
 298                  case '(':
 299                      /* walk backwards through the tokens */
 300  
 301                      if ($last >= 4 &&
 302                          $ts[$last - 1]['token'] == T_STRING &&
 303                          $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 304                          $ts[$last - 3]['token'] == ')' ) {
 305                          /* func()->method()
 306                          * 
 307                          * we can't know what func() is return, so we can't 
 308                          * say if the method() exists or not
 309                          * 
 310                          */
 311                      } else if ($last >= 3 &&
 312                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 313                          $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 314                          $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 315                          $ts[$last - 1]['token'] == T_STRING &&
 316                          $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 317                          $ts[$last - 3]['token'] == T_VARIABLE ) {
 318  
 319                          /* $object->method( */
 320  
 321                          /* catch (Exception $e) does not set $e in $GLOBALS[] */
 322                          $in_catch = 0;
 323  
 324                          foreach ($ts as $v) {
 325                              if ($v['token'] == T_CATCH) {
 326                                  $in_catch = 1;
 327                              }
 328                          }
 329  
 330                          if (!$in_catch) {
 331                              /* $object has to exist and has to be a object */
 332                              $objname = $ts[$last - 3]['value'];
 333                     
 334                              if (!isset($GLOBALS[ltrim($objname, '$')])) {
 335                                  throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 336                              }
 337                              $object = $GLOBALS[ltrim($objname, '$')];
 338      
 339                              if (!is_object($object)) {
 340                                  throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 341                              }
 342                              
 343                              $method = $ts[$last - 1]['value'];
 344  
 345                              /* obj */
 346                          
 347                              if (!method_exists($object, $method)) {
 348                                  throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", 
 349                                      $objname, get_class($object), $method));
 350                              }
 351                          }
 352                      } else if ($last >= 3 &&
 353                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 354                          $ts[$last - 1]['token'] == T_VARIABLE &&
 355                          $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 356                          $ts[$last - 3]['token'] == T_VARIABLE ) {
 357  
 358                          /* $object->$method( */
 359  
 360                          /* $object has to exist and has to be a object */
 361                          $objname = $ts[$last - 3]['value'];
 362                         
 363                          if (!isset($GLOBALS[ltrim($objname, '$')])) {
 364                              throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 365                          }
 366                          $object = $GLOBALS[ltrim($objname, '$')];
 367  
 368                          if (!is_object($object)) {
 369                              throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 370                          }
 371                          
 372                          $methodname = $ts[$last - 1]['value'];
 373  
 374                          if (!isset($GLOBALS[ltrim($methodname, '$')])) {
 375                              throw new Exception(sprintf('Variable \'%s\' is not set', $methodname));
 376                          }
 377                          $method = $GLOBALS[ltrim($methodname, '$')];
 378  
 379                          /* obj */
 380                          
 381                          if (!method_exists($object, $method)) {
 382                              throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", 
 383                                  $objname, get_class($object), $method));
 384                          }
 385  
 386                      } else if ($last >= 6 &&
 387                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 388                          $ts[$last - 1]['token'] == T_STRING &&
 389                          $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 390                          $ts[$last - 3]['token'] == ']' &&
 391                              /* might be anything as index */
 392                          $ts[$last - 5]['token'] == '[' &&
 393                          $ts[$last - 6]['token'] == T_VARIABLE ) {
 394  
 395                          /* $object[...]->method( */
 396  
 397                          /* $object has to exist and has to be a object */
 398                          $objname = $ts[$last - 6]['value'];
 399                         
 400                          if (!isset($GLOBALS[ltrim($objname, '$')])) {
 401                              throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 402                          }
 403                          $array = $GLOBALS[ltrim($objname, '$')];
 404  
 405                          if (!is_array($array)) {
 406                              throw new Exception(sprintf('Variable \'%s\' is not a array', $objname));
 407                          }
 408  
 409                          $andx = $ts[$last - 4]['value'];
 410  
 411                          if (!isset($array[$andx])) {
 412                              throw new Exception(sprintf('%s[\'%s\'] is not set', $objname, $andx));
 413                          }
 414  
 415                          $object = $array[$andx];
 416  
 417                          if (!is_object($object)) {
 418                              throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 419                          }
 420                          
 421                          $method = $ts[$last - 1]['value'];
 422  
 423                          /* obj */
 424                          
 425                          if (!method_exists($object, $method)) {
 426                              throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", 
 427                                  $objname, get_class($object), $method));
 428                          }
 429  
 430                      } else if ($last >= 3 &&
 431                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 432                          $ts[$last - 1]['token'] == T_STRING &&
 433                          $ts[$last - 2]['token'] == T_DOUBLE_COLON &&
 434                          $ts[$last - 3]['token'] == T_STRING ) {
 435  
 436                          /* Class::method() */
 437  
 438                          /* $object has to exist and has to be a object */
 439                          $classname = $ts[$last - 3]['value'];
 440                         
 441                          if (!class_exists($classname)) {
 442                              throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 443                          }
 444                          
 445                          $method = $ts[$last - 1]['value'];
 446  
 447                          if (!in_array($method, get_class_methods($classname))) {
 448                              throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'", 
 449                                  $classname, $method));
 450                          }
 451                      } else if ($last >= 3 &&
 452                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 453                          $ts[$last - 1]['token'] == T_VARIABLE &&
 454                          $ts[$last - 2]['token'] == T_DOUBLE_COLON &&
 455                          $ts[$last - 3]['token'] == T_STRING ) {
 456  
 457                          /* $var::method() */
 458  
 459                          /* $object has to exist and has to be a object */
 460                          $classname = $ts[$last - 3]['value'];
 461                         
 462                          if (!class_exists($classname)) {
 463                              throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 464                          }
 465                          
 466                          $methodname = $ts[$last - 1]['value'];
 467  
 468                          if (!isset($GLOBALS[ltrim($methodname, '$')])) {
 469                              throw new Exception(sprintf('Variable \'%s\' is not set', $methodname));
 470                          }
 471                          $method = $GLOBALS[ltrim($methodname, '$')];
 472  
 473                          if (!in_array($method, get_class_methods($classname))) {
 474                              throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'", 
 475                                  $classname, $method));
 476                          }
 477  
 478                      } else if ($last >= 2 &&
 479                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 480                          $ts[$last - 1]['token'] == T_STRING &&
 481                          $ts[$last - 2]['token'] == T_NEW ) {
 482  
 483                          /* new Class() */
 484  
 485                          /* don't care about this in a class ... { ... } */
 486  
 487                          $classname = $ts[$last - 1]['value'];
 488  
 489                          if (!class_exists($classname)) {
 490                              throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 491                          }
 492  
 493                          $r = new ReflectionClass($classname);
 494  
 495                          if ($r->isAbstract()) {
 496                              throw new Exception(sprintf("Can't instantiate abstract Class '%s'", $classname));
 497                          }
 498  
 499                          if (!$r->isInstantiable()) {
 500                              throw new Exception(sprintf('Class \'%s\' can\'t be instantiated. Is the class abstract ?', $classname));
 501                          }
 502  
 503                      } else if ($last >= 2 &&
 504                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 505                          $ts[$last - 1]['token'] == T_STRING &&
 506                          $ts[$last - 2]['token'] == T_FUNCTION ) {
 507  
 508                          /* make sure we are not a in class definition */
 509  
 510                          /* function a() */
 511  
 512                          $func = $ts[$last - 1]['value'];
 513  
 514                          if (function_exists($func)) {
 515                              throw new Exception(sprintf('Function \'%s\' is already defined', $func));
 516                          }
 517                      } else if ($last >= 4 &&
 518                          $ts[0]['token'] == T_CLASS &&
 519                          $ts[1]['token'] == T_STRING &&
 520                          $ts[$last - 1]['token'] == T_STRING &&
 521                          $ts[$last - 2]['token'] == T_FUNCTION ) {
 522  
 523                          /* make sure we are not a in class definition */
 524  
 525                          /* class a { .. function a() ... } */
 526  
 527                          $func = $ts[$last - 1]['value'];
 528                          $classname = $ts[1]['value'];
 529  
 530                          if (isset($methods[$func])) {
 531                              throw new Exception(sprintf("Can't redeclare method '%s' in Class '%s'", $func, $classname));
 532                          }
 533  
 534                          $methods[$func] = 1;
 535  
 536                      } else if ($last >= 1 &&
 537                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 538                          $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 539                          $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 540                          $ts[$last - 1]['token'] == T_STRING ) {
 541                          /* func() */
 542                          $funcname = $ts[$last - 1]['value'];
 543                          
 544                          if (!function_exists($funcname)) {
 545                              throw new Exception(sprintf("Function %s() doesn't exist", $funcname));
 546                          }
 547                      } else if ($last >= 1 &&
 548                          $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 549                          $ts[$last - 1]['token'] == T_VARIABLE ) {
 550      
 551                          /* $object has to exist and has to be a object */
 552                          $funcname = $ts[$last - 1]['value'];
 553                         
 554                          if (!isset($GLOBALS[ltrim($funcname, '$')])) {
 555                              throw new Exception(sprintf('Variable \'%s\' is not set', $funcname));
 556                          }
 557                          $func = $GLOBALS[ltrim($funcname, '$')];
 558  
 559                          if (!function_exists($func)) {
 560                              throw new Exception(sprintf("Function %s() doesn't exist", $func));
 561                          }
 562  
 563                      }
 564                      
 565                      array_push($braces, $token);
 566                      break;
 567                  case '{':
 568                      $need_return = 0;
 569  
 570                      if ($last >= 2 &&
 571                          $ts[$last - 1]['token'] == T_STRING &&
 572                          $ts[$last - 2]['token'] == T_CLASS ) {
 573  
 574                          /* class name { */
 575  
 576                          $classname = $ts[$last - 1]['value'];
 577  
 578                          if (class_exists($classname, false)) {
 579                              throw new Exception(sprintf("Class '%s' can't be redeclared", $classname));
 580                          }
 581                      } else if ($last >= 4 &&
 582                          $ts[$last - 1]['token'] == T_STRING &&
 583                          $ts[$last - 2]['token'] == T_EXTENDS &&
 584                          $ts[$last - 3]['token'] == T_STRING &&
 585                          $ts[$last - 4]['token'] == T_CLASS ) {
 586  
 587                          /* class classname extends classname { */
 588  
 589                          $classname = $ts[$last - 3]['value'];
 590                          $extendsname = $ts[$last - 1]['value'];
 591  
 592                          if (class_exists($classname, false)) {
 593                              throw new Exception(sprintf("Class '%s' can't be redeclared", 
 594                                  $classname));
 595                          }
 596                          if (!class_exists($extendsname, true)) {
 597                              throw new Exception(sprintf("Can't extend '%s' ... from not existing Class '%s'", 
 598                                  $classname, $extendsname));
 599                          }
 600                      } else if ($last >= 4 &&
 601                          $ts[$last - 1]['token'] == T_STRING &&
 602                          $ts[$last - 2]['token'] == T_IMPLEMENTS &&
 603                          $ts[$last - 3]['token'] == T_STRING &&
 604                          $ts[$last - 4]['token'] == T_CLASS ) {
 605  
 606                          /* class name implements interface { */
 607  
 608                          $classname = $ts[$last - 3]['value'];
 609                          $implements = $ts[$last - 1]['value'];
 610  
 611                          if (class_exists($classname, false)) {
 612                              throw new Exception(sprintf("Class '%s' can't be redeclared", 
 613                                  $classname));
 614                          }
 615                          if (!interface_exists($implements, false)) {
 616                              throw new Exception(sprintf("Can't implement not existing Interface '%s' for Class '%s'", 
 617                                  $implements, $classname));
 618                          }
 619                      }
 620  
 621                      array_push($braces, $token);
 622                      break;
 623                  case '}':
 624                      $need_return = 0;
 625                  case ')':
 626                      array_pop($braces);
 627                      break;
 628                  case '[':
 629                      if ($ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 630                          $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 631                          $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 632                          $ts[$last - 1]['token'] == T_VARIABLE) {
 633                          /* $a[] only works on array and string */
 634  
 635                          /* $object has to exist and has to be a object */
 636                          $objname = $ts[$last - 1]['value'];
 637                         
 638                          if (!isset($GLOBALS[ltrim($objname, '$')])) {
 639                              throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 640                          }
 641                          $obj = $GLOBALS[ltrim($objname, '$')];
 642  
 643                          if (is_object($obj)) {
 644                              throw new Exception(sprintf('Objects (%s) don\'t support array access operators', $objname));
 645                          }
 646                      }
 647                      break;
 648                  }
 649                    
 650                  $eval .= $token;
 651              }    
 652          }
 653  
 654          $last = count($ts) - 1;
 655          if ($last >= 2 &&
 656              $ts[$last - 0]['token'] == T_STRING &&
 657              $ts[$last - 1]['token'] == T_DOUBLE_COLON &&
 658              $ts[$last - 2]['token'] == T_STRING ) {
 659  
 660              /* Class::constant */
 661  
 662              /* $object has to exist and has to be a object */
 663              $classname = $ts[$last - 2]['value'];
 664             
 665              if (!class_exists($classname)) {
 666                  throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 667              }
 668              
 669              $constname = $ts[$last - 0]['value'];
 670  
 671              $c = new ReflectionClass($classname);
 672              if (!$c->hasConstant($constname)) {
 673                  throw new Exception(sprintf("Class '%s' doesn't have a constant named '%s'", 
 674                      $classname, $constname));
 675              }
 676          } else if ($last == 0 &&
 677              $ts[$last - 0]['token'] == T_VARIABLE ) {
 678  
 679              /* $var */
 680  
 681              $varname = $ts[$last - 0]['value'];
 682             
 683              if (!isset($GLOBALS[ltrim($varname, '$')])) {
 684                  throw new Exception(sprintf('Variable \'%s\' is not set', $varname));
 685              }
 686          }
 687  
 688  
 689          $need_more = (count($braces) > 0) || $open_comment;
 690  
 691          if ($need_more || ';' === $token) {
 692              $need_semicolon = 0;
 693          }  
 694    
 695          if ($need_return) {
 696              $eval = "return ".$eval;
 697          }
 698   
 699          /* add a traling ; if necessary */ 
 700          if ($need_semicolon) 
 701          {
 702              $this->has_semicolon = preg_match('/;\s*$/', $eval);
 703              $eval .= ';';
 704          }
 705          
 706          if (!$need_more) {
 707              $this->code = $eval;
 708          }
 709                  
 710          return $need_more;
 711      }
 712      
 713      /**
 714      * show the prompt and fetch a single line
 715      * 
 716      * uses readline() if avaialbe
 717      * 
 718      * @return string a input-line
 719      */
 720      public function readline() {
 721          if (empty($this->code)) print PHP_EOL;
 722  
 723          $prompt = (empty($this->code)) ? '>> ' : '.. ';
 724  
 725          if (count($this->code_buffer) > 0) {
 726              print $prompt;
 727  
 728              $line = array_shift($this->code_buffer);
 729  
 730              print $line.PHP_EOL;
 731  
 732              return $line.PHP_EOL;
 733          }
 734  
 735          if ($this->have_readline) {
 736              $l = readline($prompt);
 737  
 738              readline_add_history($l);
 739          } else {
 740              print $prompt;
 741  
 742              if (is_null($this->stdin)) {
 743                  if (false === ($this->stdin = fopen("php://stdin", "r"))) {
 744                      return false;
 745                  }
 746              }
 747              $l = fgets($this->stdin);
 748          }
 749          return $l;
 750      }
 751  
 752      /**
 753      * get the inline help
 754      *
 755      * @return string the inline help as string 
 756      */
 757      public function cmdHelp($l) {
 758          $o = 'Inline Help:'.PHP_EOL;
 759  
 760          $cmds = PHP_Shell_Commands::getInstance()->getCommands();
 761  
 762          foreach ($cmds as $cmd) {
 763              $o .= sprintf('  >> %s'.PHP_EOL.'    %s'.PHP_EOL,
 764                  $cmd['command'],
 765                  $cmd['description']
 766              );
 767          }
 768  
 769          return var_export($o, 1);
 770      }
 771  
 772      /**
 773      * get the license string
 774      *
 775      * @return string the inline help as string 
 776      */
 777      public function cmdLicense($l) {
 778          $o = <<<EOF
 779  (c) 2006 Jan Kneschke <jan@kneschke.de>
 780  
 781  Permission is hereby granted, free of charge, to any person obtaining a copy of
 782  this software and associated documentation files (the "Software"), to deal in
 783  the Software without restriction, including without limitation the rights to
 784  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 785  of the Software, and to permit persons to whom the Software is furnished to do
 786  so, subject to the following conditions:
 787  
 788  The above copyright notice and this permission notice shall be included in all
 789  copies or substantial portions of the Software.
 790  
 791  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 792  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 793  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 794  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 795  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 796  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 797  SOFTWARE.
 798  EOF;
 799  
 800          return var_export($o, 1);
 801      }
 802  
 803      /**
 804      * handle the 'quit' command
 805      *
 806      * @return bool false to leave the input() call
 807      * @see input
 808      */
 809      protected function cmdQuit($l) {
 810          return false;
 811      }
 812  
 813      /**
 814      * handle the input line
 815      *
 816      * read the input and handle the commands of the shell
 817      *
 818      * @return bool false on 'quit' or EOF, true otherwise
 819      */
 820      public function input() {
 821          $l = $this->readline();
 822  
 823          /* got EOF ? */
 824          if (false === $l) return false;
 825  
 826          $l = trim($l);
 827          
 828          if (empty($this->code)) {
 829              $this->verbose = 0;
 830  
 831              $cmds = PHP_Shell_Commands::getInstance()->getCommands();
 832  
 833              foreach ($cmds as $cmd) {
 834                  if (preg_match($cmd['regex'], $l)) {
 835                      $obj = $cmd['obj'];
 836                      $func = $cmd['method'];
 837  
 838                      if (false === ($l = $obj->$func($l))) {
 839                          ## quit
 840                          return false;
 841                      }
 842  
 843                      if (is_array($l)) {
 844                          $this->code_buffer = $l;
 845                          $l = '';
 846                      }
 847                      break;
 848                  }
 849              }
 850          }
 851         
 852          $this->appendCode($l); 
 853  
 854          return true;
 855      }
 856     
 857      /**
 858      * get the code-buffer
 859      * 
 860      * @return string the code-buffer
 861      */
 862      public function getCode() {
 863          return $this->code;
 864          return $code;
 865      }
 866      
 867      /**
 868      * reset the code-buffer
 869      */
 870      public function resetCode() {
 871          $this->has_semicolon=false;
 872          $this->code = '';
 873      }
 874   
 875      /**
 876      * append code to the code-buffer
 877      *
 878      * @param string $code input buffer
 879      */
 880      public function appendCode($code) {
 881          if (strlen($code)) $code .= PHP_EOL;
 882  
 883          $this->code .= $code;
 884      }
 885     
 886      /**
 887      * check if readline support is enabled
 888      *
 889      * @return bool true if enabled, false otherwise
 890      */
 891      public function hasReadline() {
 892          return $this->have_readline;
 893      }
 894  
 895      /**
 896      * get version of the class
 897      *
 898      * @return string version-string
 899      */
 900      public function getVersion() {
 901          return $this->version;
 902      }
 903  }
 904  
 905  /**
 906  * a readline completion callback
 907  *
 908  * @param string $str linebuffer
 909  * @param integer $pos position in linebuffer
 910  * @return array list of possible matches
 911  */
 912  function __shell_readline_complete($str, $pos) {
 913      $in = readline_info('line_buffer');
 914  
 915      /**
 916      * parse the line-buffer backwards to see if we have a 
 917      * - constant
 918      * - function 
 919      * - variable
 920      */
 921  
 922      $m = array();
 923  
 924      if (preg_match('#\$([A-Za-z0-9_]+)->#', $in, $a)) {
 925          /* check for $o->... */
 926          $name = $a[1];
 927  
 928          if (isset($GLOBALS[$name]) && is_object($GLOBALS[$name])) {
 929              $c = get_class_methods($GLOBALS[$name]);
 930  
 931              foreach ($c as $v) {
 932                  $m[] = $v.'(';
 933              }
 934              $c = get_class_vars(get_class($GLOBALS[$name]));
 935  
 936              foreach ($c as $k => $v) {
 937                  $m[] = $k;
 938              }
 939  
 940              return $m;
 941          }
 942      } else if (preg_match('#\$([A-Za-z0-9_]+)\[([^\]]+)\]->#', $in, $a)) {
 943          /* check for $o[...]->... */
 944          $name = $a[1];
 945  
 946          if (isset($GLOBALS[$name]) && 
 947              is_array($GLOBALS[$name]) &&
 948              isset($GLOBALS[$name][$a[2]])) {
 949  
 950              $c = get_class_methods($GLOBALS[$name][$a[2]]);
 951  
 952              foreach ($c as $v) {
 953                  $m[] = $v.'(';
 954              }
 955              $c = get_class_vars(get_class($GLOBALS[$name][$a[2]]));
 956  
 957              foreach ($c as $k => $v) {
 958                  $m[] = $k;
 959              }
 960              return $m;
 961          }
 962  
 963      } else if (preg_match('#([A-Za-z0-9_]+)::#', $in, $a)) {
 964          /* check for Class:: */
 965          $name = $a[1];
 966  
 967          if (class_exists($name, false)) {
 968              $c = get_class_methods($name);
 969  
 970              foreach ($c as $v) {
 971                  $m[] = sprintf('%s::%s(', $name, $v);
 972              }
 973  
 974              $cl = new ReflectionClass($name);
 975              $c = $cl->getConstants();
 976  
 977              foreach ($c as $k => $v) {
 978                  $m[] = sprintf('%s::%s', $name, $k);
 979              }
 980  
 981              return $m;
 982          }
 983      } else if (preg_match('#\$([a-zA-Z]?[a-zA-Z0-9_]*)$#', $in)) {
 984          $m = array_keys($GLOBALS);
 985  
 986          return $m;
 987      } else if (preg_match('#new #', $in)) {
 988          $c = get_declared_classes();
 989      
 990          foreach ($c as $v) {
 991              $m[] = $v.'(';
 992          }
 993  
 994          return $m;
 995      } else if (preg_match('#^:set #', $in)) {
 996          foreach (PHP_Shell_Options::getInstance()->getOptions() as $v) {
 997              $m[] = $v;
 998          }
 999  
1000          return $m;
1001      }
1002  
1003      $f = get_defined_functions();
1004  
1005      foreach ($f['internal'] as $v) {
1006          $m[] = $v.'(';
1007      }
1008  
1009      foreach ($f['user'] as $v) {
1010          $m[] = $v.'(';
1011      }
1012      
1013      $c = get_declared_classes();
1014  
1015      foreach ($c as $v) {
1016          $m[] = $v.'::';
1017      }
1018  
1019      $c = get_defined_constants();
1020  
1021      foreach ($c as $k => $v) {
1022          $m[] = $k;
1023      }
1024  
1025      /* taken from http://de3.php.net/manual/en/reserved.php */
1026      $m[] = 'abstract';
1027      $m[] = 'and';
1028      $m[] = 'array(';
1029      $m[] = 'as';
1030      $m[] = 'break';
1031      $m[] = 'case';
1032      $m[] = 'catch';
1033      $m[] = 'class';
1034      $m[] = 'const';
1035      $m[] = 'continue';
1036      # $m[] = 'declare';
1037      $m[] = 'default';
1038      $m[] = 'die(';
1039      $m[] = 'do';
1040      $m[] = 'echo(';
1041      $m[] = 'else';
1042      $m[] = 'elseif';
1043      $m[] = 'empty(';
1044      # $m[] = 'enddeclare';
1045      $m[] = 'eval(';
1046      $m[] = 'exception';
1047      $m[] = 'extends';
1048      $m[] = 'exit(';
1049      $m[] = 'extends';
1050      $m[] = 'final';
1051      $m[] = 'for (';
1052      $m[] = 'foreach (';
1053      $m[] = 'function';
1054      $m[] = 'global';
1055      $m[] = 'if';
1056      $m[] = 'implements';
1057      $m[] = 'include "';
1058      $m[] = 'include_once "';
1059      $m[] = 'interface';
1060      $m[] = 'isset(';
1061      $m[] = 'list(';
1062      $m[] = 'new';
1063      $m[] = 'or';
1064      $m[] = 'print(';
1065      $m[] = 'private';
1066      $m[] = 'protected';
1067      $m[] = 'public';
1068      $m[] = 'require "';
1069      $m[] = 'require_once "';
1070      $m[] = 'return';
1071      $m[] = 'static';
1072      $m[] = 'switch (';
1073      $m[] = 'throw';
1074      $m[] = 'try';
1075      $m[] = 'unset(';
1076      # $m[] = 'use';
1077      $m[] = 'var';
1078      $m[] = 'while';
1079      $m[] = 'xor';
1080      $m[] = '__FILE__';
1081      $m[] = '__FUNCTION__';
1082      $m[] = '__CLASS__';
1083      $m[] = '__LINE__';
1084      $m[] = '__METHOD__';
1085  
1086      # printf("%s ... %s\n", $str, $pos);
1087      return $m;
1088  }
1089  
1090  


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7