diff options
| author | ctrlaltca <> | 2012-07-12 11:21:01 +0000 | 
|---|---|---|
| committer | ctrlaltca <> | 2012-07-12 11:21:01 +0000 | 
| commit | 903ae8a581fac1e6917fc3e31d2ad8fb91df80c3 (patch) | |
| tree | e08bf04f0823650a231227ac3499121270172a23 /framework/3rdParty/PhpShell/PHP | |
| parent | 3e4e6e66aeb3f8fea4e1eb4237498ef9d2358f63 (diff) | |
standardize the use of unix eol; use svn properties to enforce native eol
Diffstat (limited to 'framework/3rdParty/PhpShell/PHP')
| -rw-r--r-- | framework/3rdParty/PhpShell/PHP/Shell.php | 2182 | 
1 files changed, 1091 insertions, 1091 deletions
diff --git a/framework/3rdParty/PhpShell/PHP/Shell.php b/framework/3rdParty/PhpShell/PHP/Shell.php index bf8c86c3..8012475e 100644 --- a/framework/3rdParty/PhpShell/PHP/Shell.php +++ b/framework/3rdParty/PhpShell/PHP/Shell.php @@ -1,1091 +1,1091 @@ -<?php
 -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 -
 -/*
 -(c) 2006 Jan Kneschke <jan@kneschke.de>
 -
 -Permission is hereby granted, free of charge, to any person obtaining a copy of
 -this software and associated documentation files (the "Software"), to deal in
 -the Software without restriction, including without limitation the rights to
 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 -of the Software, and to permit persons to whom the Software is furnished to do
 -so, subject to the following conditions:
 -
 -The above copyright notice and this permission notice shall be included in all
 -copies or substantial portions of the Software.
 -
 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 -SOFTWARE.
 -*/
 -
 -/**
 -* A interactive PHP Shell
 -*
 -* The more I work with other languages like python and ruby I like their way how they
 -* work on problems. While PHP is very forgiving on errors, it is weak on the debugging
 -* side. It was missing a simple to use interactive shell for years. Python and Ruby have
 -* their ipython and iruby shell which give you a direct way to interact with the objects.
 -* No need to write a script and execute it afterwards.
 -*
 -* Starting the Shell:
 -*
 -* The package contains a shell wrapper for windows and unix:
 -* <pre>
 -* sh>  php-shell.sh
 -* win> php-shell
 -* </pre>
 -*
 -* Both are calling the wrapper script <code>php -q php-shell-cmd.php</code>
 -*
 -* Inline Help
 -*
 -* <pre>
 -* PHP-Shell - Version 0.2.0, with readline() support
 -* (c) 2006, Jan Kneschke <jan@kneschke.de>
 -*
 -* >> use '?' to open the inline help
 -*
 -* >> ?
 -* "inline help for the PHP-shell
 -*
 -*   >> ?
 -*     print this help
 -*   >> ? <topic>
 -*     get the doccomment for a class, method, property or function
 -*   >> p <var>
 -*     execute a verbose print (if implemented)
 -*   >> quit
 -*     leave shell
 -* "
 -* >> ? PHP_Shell
 -* </pre>
 -* Alternatives
 -*
 -* - http://david.acz.org/phpa/
 -* - http://www.hping.org/phpinteractive/
 -* - the embedded interactive php-shell: $ php -a
 -*
 -* @package PHP
 -*/
 -
 -/**
 -* PHP_Shell
 -*
 -* a interactive PHP Shell with tab-completion and history
 -* it can catch FATAL errors before executing the code
 -*
 -* Extensions are provided through three side-classes:
 -*
 -* - PHP_Shell_Commands
 -* - PHP_Shell_Options
 -* - PHP_Shell_Extensions
 -*
 -* @package PHP
 -*/
 -
 -require_once(dirname(__FILE__)."/Shell/Commands.php");
 -require_once(dirname(__FILE__)."/Shell/Options.php"); /* for the tab-complete */
 -
 -class PHP_Shell {
 -    /**
 -    * current code-buffer
 -    * @var string
 -    */
 -    protected $code;
 -
 -    /**
 -    * set if readline support is enabled
 -    * @var bool
 -    */
 -    protected $have_readline;
 -
 -    /**
 -    * current version of the class
 -    * @var string
 -    */
 -    protected $version = '0.3.1';
 -
 -    /**
 -    *
 -    */
 -    protected $stdin;
 -
 -    protected $code_buffer;
 -
 -	public $has_semicolon=false;
 -
 -    /**
 -    * init the shell and change if readline support is available
 -    */
 -    public function __construct() {
 -        $this->code = '';
 -
 -        $this->stdin = null;
 -
 -        $this->have_readline = function_exists('readline');
 -
 -        if ($this->have_readline) {
 -            readline_completion_function('__shell_readline_complete');
 -        }
 -
 -        $this->use_readline = true;
 -
 -        $cmd = PHP_Shell_Commands::getInstance();
 -
 -        $cmd->registerCommand('#^quit$#', $this, 'cmdQuit', 'quit', 'leaves the shell');
 -        $cmd->registerCommand('#^\?$#', $this, 'cmdHelp', '?', 'show this help');
 -        $cmd->registerCommand('#^\?\s+license$#', $this, 'cmdLicense', '? license', 'show license of the shell');
 -    }
 -
 -
 -    /**
 -    * parse the PHP code
 -    *
 -    * we parse before we eval() the code to
 -    * - fetch fatal errors before they come up
 -    * - know about where we have to wait for closing braces
 -    *
 -    * @return int 0 if a executable statement is in the code-buffer, non-zero otherwise
 -    */
 -    public function parse() {
 -        ## remove empty lines
 -        if (trim($this->code) == '') return 1;
 -
 -        $t = token_get_all('<?php '.$this->code.' ?>');
 -
 -        $need_semicolon = 1; /* do we need a semicolon to complete the statement ? */
 -        $need_return = 1;    /* can we prepend a return to the eval-string ? */
 -        $open_comment = 0;   /* a open multi-line comment */
 -        $eval = '';          /* code to be eval()'ed later */
 -        $braces = array();   /* to track if we need more closing braces */
 -
 -        $methods = array();  /* to track duplicate methods in a class declaration */
 -        $ts = array();       /* tokens without whitespaces */
 -
 -        foreach ($t as $ndx => $token) {
 -            if (is_array($token)) {
 -                $ignore = 0;
 -
 -                switch($token[0]) {
 -                case T_WHITESPACE:
 -                case T_OPEN_TAG:
 -                case T_CLOSE_TAG:
 -                    $ignore = 1;
 -                    break;
 -                case T_FOREACH:
 -                case T_DO:
 -                case T_WHILE:
 -                case T_FOR:
 -
 -                case T_IF:
 -                case T_RETURN:
 -
 -                case T_CLASS:
 -                case T_FUNCTION:
 -                case T_INTERFACE:
 -
 -                case T_PRINT:
 -                case T_ECHO:
 -
 -                case T_COMMENT:
 -                case T_UNSET:
 -
 -                case T_INCLUDE:
 -                case T_REQUIRE:
 -                case T_INCLUDE_ONCE:
 -                case T_REQUIRE_ONCE:
 -                case T_TRY:
 -                case T_SWITCH:
 -                case T_DEFAULT:
 -                case T_CASE:
 -                case T_BREAK:
 -                case T_DOC_COMMENT:
 -                    $need_return = 0;
 -                    break;
 -                case T_EMPTY:
 -                case T_ISSET:
 -                case T_EVAL:
 -                case T_EXIT:
 -
 -                case T_VARIABLE:
 -                case T_STRING:
 -                case T_NEW:
 -                case T_EXTENDS:
 -                case T_IMPLEMENTS:
 -                case T_OBJECT_OPERATOR:
 -                case T_DOUBLE_COLON:
 -                case T_INSTANCEOF:
 -
 -                case T_CATCH:
 -                case T_THROW:
 -
 -                case T_ELSE:
 -                case T_AS:
 -                case T_LNUMBER:
 -                case T_DNUMBER:
 -                case T_CONSTANT_ENCAPSED_STRING:
 -                case T_ENCAPSED_AND_WHITESPACE:
 -                case T_CHARACTER:
 -                case T_ARRAY:
 -                case T_DOUBLE_ARROW:
 -
 -                case T_CONST:
 -                case T_PUBLIC:
 -                case T_PROTECTED:
 -                case T_PRIVATE:
 -                case T_ABSTRACT:
 -                case T_STATIC:
 -                case T_VAR:
 -
 -                case T_INC:
 -                case T_DEC:
 -                case T_SL:
 -                case T_SL_EQUAL:
 -                case T_SR:
 -                case T_SR_EQUAL:
 -
 -                case T_IS_EQUAL:
 -                case T_IS_IDENTICAL:
 -                case T_IS_GREATER_OR_EQUAL:
 -                case T_IS_SMALLER_OR_EQUAL:
 -
 -                case T_BOOLEAN_OR:
 -                case T_LOGICAL_OR:
 -                case T_BOOLEAN_AND:
 -                case T_LOGICAL_AND:
 -                case T_LOGICAL_XOR:
 -                case T_MINUS_EQUAL:
 -                case T_PLUS_EQUAL:
 -                case T_MUL_EQUAL:
 -                case T_DIV_EQUAL:
 -                case T_MOD_EQUAL:
 -                case T_XOR_EQUAL:
 -                case T_AND_EQUAL:
 -                case T_OR_EQUAL:
 -
 -                case T_FUNC_C:
 -                case T_CLASS_C:
 -                case T_LINE:
 -                case T_FILE:
 -
 -                case T_BOOL_CAST:
 -                case T_INT_CAST:
 -                case T_STRING_CAST:
 -
 -                    /* just go on */
 -                    break;
 -                default:
 -                    /* debug unknown tags*/
 -                    error_log(sprintf("unknown tag: %d (%s): %s".PHP_EOL, $token[0], token_name($token[0]), $token[1]));
 -
 -                    break;
 -                }
 -                if (!$ignore) {
 -                    $eval .= $token[1]." ";
 -                    $ts[] = array("token" => $token[0], "value" => $token[1]);
 -                }
 -            } else {
 -                $ts[] = array("token" => $token, "value" => '');
 -
 -                $last = count($ts) - 1;
 -
 -                switch ($token) {
 -                case '(':
 -                    /* walk backwards through the tokens */
 -
 -                    if ($last >= 4 &&
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 -                        $ts[$last - 3]['token'] == ')' ) {
 -                        /* func()->method()
 -                        *
 -                        * we can't know what func() is return, so we can't
 -                        * say if the method() exists or not
 -                        *
 -                        */
 -                    } else if ($last >= 3 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 -                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 -                        $ts[$last - 3]['token'] == T_VARIABLE ) {
 -
 -                        /* $object->method( */
 -
 -                        /* catch (Exception $e) does not set $e in $GLOBALS[] */
 -                        $in_catch = 0;
 -
 -                        foreach ($ts as $v) {
 -                            if ($v['token'] == T_CATCH) {
 -                                $in_catch = 1;
 -                            }
 -                        }
 -
 -                        if (!$in_catch) {
 -                            /* $object has to exist and has to be a object */
 -                            $objname = $ts[$last - 3]['value'];
 -
 -                            if (!isset($GLOBALS[ltrim($objname, '$')])) {
 -                                throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 -                            }
 -                            $object = $GLOBALS[ltrim($objname, '$')];
 -
 -                            if (!is_object($object)) {
 -                                throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 -                            }
 -
 -                            $method = $ts[$last - 1]['value'];
 -
 -                            /* obj */
 -
 -                            if (!method_exists($object, $method)) {
 -                                throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'",
 -                                    $objname, get_class($object), $method));
 -                            }
 -                        }
 -                    } else if ($last >= 3 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_VARIABLE &&
 -                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 -                        $ts[$last - 3]['token'] == T_VARIABLE ) {
 -
 -                        /* $object->$method( */
 -
 -                        /* $object has to exist and has to be a object */
 -                        $objname = $ts[$last - 3]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($objname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 -                        }
 -                        $object = $GLOBALS[ltrim($objname, '$')];
 -
 -                        if (!is_object($object)) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 -                        }
 -
 -                        $methodname = $ts[$last - 1]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($methodname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $methodname));
 -                        }
 -                        $method = $GLOBALS[ltrim($methodname, '$')];
 -
 -                        /* obj */
 -
 -                        if (!method_exists($object, $method)) {
 -                            throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'",
 -                                $objname, get_class($object), $method));
 -                        }
 -
 -                    } else if ($last >= 6 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
 -                        $ts[$last - 3]['token'] == ']' &&
 -                            /* might be anything as index */
 -                        $ts[$last - 5]['token'] == '[' &&
 -                        $ts[$last - 6]['token'] == T_VARIABLE ) {
 -
 -                        /* $object[...]->method( */
 -
 -                        /* $object has to exist and has to be a object */
 -                        $objname = $ts[$last - 6]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($objname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 -                        }
 -                        $array = $GLOBALS[ltrim($objname, '$')];
 -
 -                        if (!is_array($array)) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not a array', $objname));
 -                        }
 -
 -                        $andx = $ts[$last - 4]['value'];
 -
 -                        if (!isset($array[$andx])) {
 -                            throw new Exception(sprintf('%s[\'%s\'] is not set', $objname, $andx));
 -                        }
 -
 -                        $object = $array[$andx];
 -
 -                        if (!is_object($object)) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not a class', $objname));
 -                        }
 -
 -                        $method = $ts[$last - 1]['value'];
 -
 -                        /* obj */
 -
 -                        if (!method_exists($object, $method)) {
 -                            throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'",
 -                                $objname, get_class($object), $method));
 -                        }
 -
 -                    } else if ($last >= 3 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_DOUBLE_COLON &&
 -                        $ts[$last - 3]['token'] == T_STRING ) {
 -
 -                        /* Class::method() */
 -
 -                        /* $object has to exist and has to be a object */
 -                        $classname = $ts[$last - 3]['value'];
 -
 -                        if (!class_exists($classname)) {
 -                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 -                        }
 -
 -                        $method = $ts[$last - 1]['value'];
 -
 -                        if (!in_array($method, get_class_methods($classname))) {
 -                            throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'",
 -                                $classname, $method));
 -                        }
 -                    } else if ($last >= 3 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_VARIABLE &&
 -                        $ts[$last - 2]['token'] == T_DOUBLE_COLON &&
 -                        $ts[$last - 3]['token'] == T_STRING ) {
 -
 -                        /* $var::method() */
 -
 -                        /* $object has to exist and has to be a object */
 -                        $classname = $ts[$last - 3]['value'];
 -
 -                        if (!class_exists($classname)) {
 -                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 -                        }
 -
 -                        $methodname = $ts[$last - 1]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($methodname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $methodname));
 -                        }
 -                        $method = $GLOBALS[ltrim($methodname, '$')];
 -
 -                        if (!in_array($method, get_class_methods($classname))) {
 -                            throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'",
 -                                $classname, $method));
 -                        }
 -
 -                    } else if ($last >= 2 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_NEW ) {
 -
 -                        /* new Class() */
 -
 -                        /* don't care about this in a class ... { ... } */
 -
 -                        $classname = $ts[$last - 1]['value'];
 -
 -                        if (!class_exists($classname)) {
 -                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 -                        }
 -
 -                        $r = new ReflectionClass($classname);
 -
 -                        if ($r->isAbstract()) {
 -                            throw new Exception(sprintf("Can't instantiate abstract Class '%s'", $classname));
 -                        }
 -
 -                        if (!$r->isInstantiable()) {
 -                            throw new Exception(sprintf('Class \'%s\' can\'t be instantiated. Is the class abstract ?', $classname));
 -                        }
 -
 -                    } else if ($last >= 2 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_FUNCTION ) {
 -
 -                        /* make sure we are not a in class definition */
 -
 -                        /* function a() */
 -
 -                        $func = $ts[$last - 1]['value'];
 -
 -                        if (function_exists($func)) {
 -                            throw new Exception(sprintf('Function \'%s\' is already defined', $func));
 -                        }
 -                    } else if ($last >= 4 &&
 -                        $ts[0]['token'] == T_CLASS &&
 -                        $ts[1]['token'] == T_STRING &&
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_FUNCTION ) {
 -
 -                        /* make sure we are not a in class definition */
 -
 -                        /* class a { .. function a() ... } */
 -
 -                        $func = $ts[$last - 1]['value'];
 -                        $classname = $ts[1]['value'];
 -
 -                        if (isset($methods[$func])) {
 -                            throw new Exception(sprintf("Can't redeclare method '%s' in Class '%s'", $func, $classname));
 -                        }
 -
 -                        $methods[$func] = 1;
 -
 -                    } else if ($last >= 1 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 -                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_STRING ) {
 -                        /* func() */
 -                        $funcname = $ts[$last - 1]['value'];
 -
 -                        if (!function_exists($funcname)) {
 -                            throw new Exception(sprintf("Function %s() doesn't exist", $funcname));
 -                        }
 -                    } else if ($last >= 1 &&
 -                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_VARIABLE ) {
 -
 -                        /* $object has to exist and has to be a object */
 -                        $funcname = $ts[$last - 1]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($funcname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $funcname));
 -                        }
 -                        $func = $GLOBALS[ltrim($funcname, '$')];
 -
 -                        if (!function_exists($func)) {
 -                            throw new Exception(sprintf("Function %s() doesn't exist", $func));
 -                        }
 -
 -                    }
 -
 -                    array_push($braces, $token);
 -                    break;
 -                case '{':
 -                    $need_return = 0;
 -
 -                    if ($last >= 2 &&
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_CLASS ) {
 -
 -                        /* class name { */
 -
 -                        $classname = $ts[$last - 1]['value'];
 -
 -                        if (class_exists($classname, false)) {
 -                            throw new Exception(sprintf("Class '%s' can't be redeclared", $classname));
 -                        }
 -                    } else if ($last >= 4 &&
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_EXTENDS &&
 -                        $ts[$last - 3]['token'] == T_STRING &&
 -                        $ts[$last - 4]['token'] == T_CLASS ) {
 -
 -                        /* class classname extends classname { */
 -
 -                        $classname = $ts[$last - 3]['value'];
 -                        $extendsname = $ts[$last - 1]['value'];
 -
 -                        if (class_exists($classname, false)) {
 -                            throw new Exception(sprintf("Class '%s' can't be redeclared",
 -                                $classname));
 -                        }
 -                        if (!class_exists($extendsname, true)) {
 -                            throw new Exception(sprintf("Can't extend '%s' ... from not existing Class '%s'",
 -                                $classname, $extendsname));
 -                        }
 -                    } else if ($last >= 4 &&
 -                        $ts[$last - 1]['token'] == T_STRING &&
 -                        $ts[$last - 2]['token'] == T_IMPLEMENTS &&
 -                        $ts[$last - 3]['token'] == T_STRING &&
 -                        $ts[$last - 4]['token'] == T_CLASS ) {
 -
 -                        /* class name implements interface { */
 -
 -                        $classname = $ts[$last - 3]['value'];
 -                        $implements = $ts[$last - 1]['value'];
 -
 -                        if (class_exists($classname, false)) {
 -                            throw new Exception(sprintf("Class '%s' can't be redeclared",
 -                                $classname));
 -                        }
 -                        if (!interface_exists($implements, false)) {
 -                            throw new Exception(sprintf("Can't implement not existing Interface '%s' for Class '%s'",
 -                                $implements, $classname));
 -                        }
 -                    }
 -
 -                    array_push($braces, $token);
 -                    break;
 -                case '}':
 -                    $need_return = 0;
 -                case ')':
 -                    array_pop($braces);
 -                    break;
 -                case '[':
 -                    if ($ts[0]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */
 -                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */
 -                        $ts[$last - 1]['token'] == T_VARIABLE) {
 -                        /* $a[] only works on array and string */
 -
 -                        /* $object has to exist and has to be a object */
 -                        $objname = $ts[$last - 1]['value'];
 -
 -                        if (!isset($GLOBALS[ltrim($objname, '$')])) {
 -                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname));
 -                        }
 -                        $obj = $GLOBALS[ltrim($objname, '$')];
 -
 -                        if (is_object($obj)) {
 -                            throw new Exception(sprintf('Objects (%s) don\'t support array access operators', $objname));
 -                        }
 -                    }
 -                    break;
 -                }
 -
 -                $eval .= $token;
 -            }
 -        }
 -
 -        $last = count($ts) - 1;
 -        if ($last >= 2 &&
 -            $ts[$last - 0]['token'] == T_STRING &&
 -            $ts[$last - 1]['token'] == T_DOUBLE_COLON &&
 -            $ts[$last - 2]['token'] == T_STRING ) {
 -
 -            /* Class::constant */
 -
 -            /* $object has to exist and has to be a object */
 -            $classname = $ts[$last - 2]['value'];
 -
 -            if (!class_exists($classname)) {
 -                throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname));
 -            }
 -
 -            $constname = $ts[$last - 0]['value'];
 -
 -            $c = new ReflectionClass($classname);
 -            if (!$c->hasConstant($constname)) {
 -                throw new Exception(sprintf("Class '%s' doesn't have a constant named '%s'",
 -                    $classname, $constname));
 -            }
 -        } else if ($last == 0 &&
 -            $ts[$last - 0]['token'] == T_VARIABLE ) {
 -
 -            /* $var */
 -
 -            $varname = $ts[$last - 0]['value'];
 -
 -            if (!isset($GLOBALS[ltrim($varname, '$')])) {
 -                throw new Exception(sprintf('Variable \'%s\' is not set', $varname));
 -            }
 -        }
 -
 -
 -        $need_more = (count($braces) > 0) || $open_comment;
 -
 -        if ($need_more || ';' === $token) {
 -			$need_semicolon = 0;
 -        }
 -
 -        if ($need_return) {
 -            $eval = "return ".$eval;
 -        }
 -
 -        /* add a traling ; if necessary */
 -        if ($need_semicolon)
 -		{
 -			$this->has_semicolon = preg_match('/;\s*$/', $eval);
 -			$eval .= ';';
 -		}
 -
 -        if (!$need_more) {
 -            $this->code = $eval;
 -        }
 -
 -        return $need_more;
 -    }
 -
 -    /**
 -    * show the prompt and fetch a single line
 -    *
 -    * uses readline() if avaialbe
 -    *
 -    * @return string a input-line
 -    */
 -    public function readline() {
 -        if (empty($this->code)) print PHP_EOL;
 -
 -        $prompt = (empty($this->code)) ? '>> ' : '.. ';
 -
 -        if (count($this->code_buffer) > 0) {
 -            print $prompt;
 -
 -            $line = array_shift($this->code_buffer);
 -
 -            print $line.PHP_EOL;
 -
 -            return $line.PHP_EOL;
 -        }
 -
 -        if ($this->have_readline) {
 -            $l = readline($prompt);
 -
 -            readline_add_history($l);
 -        } else {
 -            print $prompt;
 -
 -            if (is_null($this->stdin)) {
 -                if (false === ($this->stdin = fopen("php://stdin", "r"))) {
 -                    return false;
 -                }
 -            }
 -            $l = fgets($this->stdin);
 -        }
 -        return $l;
 -    }
 -
 -    /**
 -    * get the inline help
 -    *
 -    * @return string the inline help as string
 -    */
 -    public function cmdHelp($l) {
 -        $o = 'Inline Help:'.PHP_EOL;
 -
 -        $cmds = PHP_Shell_Commands::getInstance()->getCommands();
 -
 -        $help = array();
 -        foreach ($cmds as $cmd) {
 -            $help[] = sprintf('  >> %s'.PHP_EOL.'    %s'.PHP_EOL,
 -                $cmd['command'],
 -                $cmd['description']
 -            );
 -        }
 -
 -        return var_export(implode("\n", $help), 1);
 -    }
 -
 -    /**
 -    * get the license string
 -    *
 -    * @return string the inline help as string
 -    */
 -    public function cmdLicense($l) {
 -        $o = <<<EOF
 -(c) 2006 Jan Kneschke <jan@kneschke.de>
 -
 -Permission is hereby granted, free of charge, to any person obtaining a copy of
 -this software and associated documentation files (the "Software"), to deal in
 -the Software without restriction, including without limitation the rights to
 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 -of the Software, and to permit persons to whom the Software is furnished to do
 -so, subject to the following conditions:
 -
 -The above copyright notice and this permission notice shall be included in all
 -copies or substantial portions of the Software.
 -
 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 -SOFTWARE.
 -EOF;
 -
 -        return var_export($o, 1);
 -    }
 -
 -    /**
 -    * handle the 'quit' command
 -    *
 -    * @return bool false to leave the input() call
 -    * @see input
 -    */
 -    protected function cmdQuit($l) {
 -        return false;
 -    }
 -
 -    /**
 -    * handle the input line
 -    *
 -    * read the input and handle the commands of the shell
 -    *
 -    * @return bool false on 'quit' or EOF, true otherwise
 -    */
 -    public function input() {
 -        $l = $this->readline();
 -
 -        /* got EOF ? */
 -        if (false === $l) return false;
 -
 -        $l = trim($l);
 -
 -        if (empty($this->code)) {
 -            $this->verbose = 0;
 -
 -            $cmds = PHP_Shell_Commands::getInstance()->getCommands();
 -
 -            foreach ($cmds as $cmd) {
 -                if (preg_match($cmd['regex'], $l)) {
 -                    $obj = $cmd['obj'];
 -                    $func = $cmd['method'];
 -
 -                    if (false === ($l = $obj->$func($l))) {
 -                        ## quit
 -                        return false;
 -                    }
 -
 -                    if (is_array($l)) {
 -                        $this->code_buffer = $l;
 -                        $l = '';
 -                    }
 -                    break;
 -                }
 -            }
 -        }
 -
 -        $this->appendCode($l);
 -
 -        return true;
 -    }
 -
 -    /**
 -    * get the code-buffer
 -    *
 -    * @return string the code-buffer
 -    */
 -    public function getCode() {
 -		return $this->code;
 -        return $code;
 -    }
 -
 -    /**
 -    * reset the code-buffer
 -    */
 -    public function resetCode() {
 -		$this->has_semicolon=false;
 -        $this->code = '';
 -    }
 -
 -    /**
 -    * append code to the code-buffer
 -    *
 -    * @param string $code input buffer
 -    */
 -    public function appendCode($code) {
 -        if (strlen($code)) $code .= PHP_EOL;
 -
 -        $this->code .= $code;
 -    }
 -
 -    /**
 -    * check if readline support is enabled
 -    *
 -    * @return bool true if enabled, false otherwise
 -    */
 -    public function hasReadline() {
 -        return $this->have_readline;
 -    }
 -
 -    /**
 -    * get version of the class
 -    *
 -    * @return string version-string
 -    */
 -    public function getVersion() {
 -        return $this->version;
 -    }
 -}
 -
 -/**
 -* a readline completion callback
 -*
 -* @param string $str linebuffer
 -* @param integer $pos position in linebuffer
 -* @return array list of possible matches
 -*/
 -function __shell_readline_complete($str, $pos) {
 -    $in = readline_info('line_buffer');
 -
 -    /**
 -    * parse the line-buffer backwards to see if we have a
 -    * - constant
 -    * - function
 -    * - variable
 -    */
 -
 -    $m = array();
 -
 -    if (preg_match('#\$([A-Za-z0-9_]+)->#', $in, $a)) {
 -        /* check for $o->... */
 -        $name = $a[1];
 -
 -        if (isset($GLOBALS[$name]) && is_object($GLOBALS[$name])) {
 -            $c = get_class_methods($GLOBALS[$name]);
 -
 -            foreach ($c as $v) {
 -                $m[] = $v.'(';
 -            }
 -            $c = get_class_vars(get_class($GLOBALS[$name]));
 -
 -            foreach ($c as $k => $v) {
 -                $m[] = $k;
 -            }
 -
 -            return $m;
 -        }
 -    } else if (preg_match('#\$([A-Za-z0-9_]+)\[([^\]]+)\]->#', $in, $a)) {
 -        /* check for $o[...]->... */
 -        $name = $a[1];
 -
 -        if (isset($GLOBALS[$name]) &&
 -            is_array($GLOBALS[$name]) &&
 -            isset($GLOBALS[$name][$a[2]])) {
 -
 -            $c = get_class_methods($GLOBALS[$name][$a[2]]);
 -
 -            foreach ($c as $v) {
 -                $m[] = $v.'(';
 -            }
 -            $c = get_class_vars(get_class($GLOBALS[$name][$a[2]]));
 -
 -            foreach ($c as $k => $v) {
 -                $m[] = $k;
 -            }
 -            return $m;
 -        }
 -
 -    } else if (preg_match('#([A-Za-z0-9_]+)::#', $in, $a)) {
 -        /* check for Class:: */
 -        $name = $a[1];
 -
 -        if (class_exists($name, false)) {
 -            $c = get_class_methods($name);
 -
 -            foreach ($c as $v) {
 -                $m[] = sprintf('%s::%s(', $name, $v);
 -            }
 -
 -            $cl = new ReflectionClass($name);
 -            $c = $cl->getConstants();
 -
 -            foreach ($c as $k => $v) {
 -                $m[] = sprintf('%s::%s', $name, $k);
 -            }
 -
 -            return $m;
 -        }
 -    } else if (preg_match('#\$([a-zA-Z]?[a-zA-Z0-9_]*)$#', $in)) {
 -        $m = array_keys($GLOBALS);
 -
 -        return $m;
 -    } else if (preg_match('#new #', $in)) {
 -        $c = get_declared_classes();
 -
 -        foreach ($c as $v) {
 -            $m[] = $v.'(';
 -        }
 -
 -        return $m;
 -    } else if (preg_match('#^:set #', $in)) {
 -        foreach (PHP_Shell_Options::getInstance()->getOptions() as $v) {
 -            $m[] = $v;
 -        }
 -
 -        return $m;
 -    }
 -
 -    $f = get_defined_functions();
 -
 -    foreach ($f['internal'] as $v) {
 -        $m[] = $v.'(';
 -    }
 -
 -    foreach ($f['user'] as $v) {
 -        $m[] = $v.'(';
 -    }
 -
 -    $c = get_declared_classes();
 -
 -    foreach ($c as $v) {
 -        $m[] = $v.'::';
 -    }
 -
 -    $c = get_defined_constants();
 -
 -    foreach ($c as $k => $v) {
 -        $m[] = $k;
 -    }
 -
 -    /* taken from http://de3.php.net/manual/en/reserved.php */
 -    $m[] = 'abstract';
 -    $m[] = 'and';
 -    $m[] = 'array(';
 -    $m[] = 'as';
 -    $m[] = 'break';
 -    $m[] = 'case';
 -    $m[] = 'catch';
 -    $m[] = 'class';
 -    $m[] = 'const';
 -    $m[] = 'continue';
 -    # $m[] = 'declare';
 -    $m[] = 'default';
 -    $m[] = 'die(';
 -    $m[] = 'do';
 -    $m[] = 'echo(';
 -    $m[] = 'else';
 -    $m[] = 'elseif';
 -    $m[] = 'empty(';
 -    # $m[] = 'enddeclare';
 -    $m[] = 'eval(';
 -    $m[] = 'exception';
 -    $m[] = 'extends';
 -    $m[] = 'exit(';
 -    $m[] = 'extends';
 -    $m[] = 'final';
 -    $m[] = 'for (';
 -    $m[] = 'foreach (';
 -    $m[] = 'function';
 -    $m[] = 'global';
 -    $m[] = 'if';
 -    $m[] = 'implements';
 -    $m[] = 'include "';
 -    $m[] = 'include_once "';
 -    $m[] = 'interface';
 -    $m[] = 'isset(';
 -    $m[] = 'list(';
 -    $m[] = 'new';
 -    $m[] = 'or';
 -    $m[] = 'print(';
 -    $m[] = 'private';
 -    $m[] = 'protected';
 -    $m[] = 'public';
 -    $m[] = 'require "';
 -    $m[] = 'require_once "';
 -    $m[] = 'return';
 -    $m[] = 'static';
 -    $m[] = 'switch (';
 -    $m[] = 'throw';
 -    $m[] = 'try';
 -    $m[] = 'unset(';
 -    # $m[] = 'use';
 -    $m[] = 'var';
 -    $m[] = 'while';
 -    $m[] = 'xor';
 -    $m[] = '__FILE__';
 -    $m[] = '__FUNCTION__';
 -    $m[] = '__CLASS__';
 -    $m[] = '__LINE__';
 -    $m[] = '__METHOD__';
 -
 -    # printf("%s ... %s\n", $str, $pos);
 -    return $m;
 -}
 -
 -
 +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/* +(c) 2006 Jan Kneschke <jan@kneschke.de> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** +* A interactive PHP Shell +* +* The more I work with other languages like python and ruby I like their way how they +* work on problems. While PHP is very forgiving on errors, it is weak on the debugging +* side. It was missing a simple to use interactive shell for years. Python and Ruby have +* their ipython and iruby shell which give you a direct way to interact with the objects. +* No need to write a script and execute it afterwards. +* +* Starting the Shell: +* +* The package contains a shell wrapper for windows and unix: +* <pre> +* sh>  php-shell.sh +* win> php-shell +* </pre> +* +* Both are calling the wrapper script <code>php -q php-shell-cmd.php</code> +* +* Inline Help +* +* <pre> +* PHP-Shell - Version 0.2.0, with readline() support +* (c) 2006, Jan Kneschke <jan@kneschke.de> +* +* >> use '?' to open the inline help +* +* >> ? +* "inline help for the PHP-shell +* +*   >> ? +*     print this help +*   >> ? <topic> +*     get the doccomment for a class, method, property or function +*   >> p <var> +*     execute a verbose print (if implemented) +*   >> quit +*     leave shell +* " +* >> ? PHP_Shell +* </pre> +* Alternatives +* +* - http://david.acz.org/phpa/ +* - http://www.hping.org/phpinteractive/ +* - the embedded interactive php-shell: $ php -a +* +* @package PHP +*/ + +/** +* PHP_Shell +* +* a interactive PHP Shell with tab-completion and history +* it can catch FATAL errors before executing the code +* +* Extensions are provided through three side-classes: +* +* - PHP_Shell_Commands +* - PHP_Shell_Options +* - PHP_Shell_Extensions +* +* @package PHP +*/ + +require_once(dirname(__FILE__)."/Shell/Commands.php"); +require_once(dirname(__FILE__)."/Shell/Options.php"); /* for the tab-complete */ + +class PHP_Shell { +    /** +    * current code-buffer +    * @var string +    */ +    protected $code; + +    /** +    * set if readline support is enabled +    * @var bool +    */ +    protected $have_readline; + +    /** +    * current version of the class +    * @var string +    */ +    protected $version = '0.3.1'; + +    /** +    * +    */ +    protected $stdin; + +    protected $code_buffer; + +	public $has_semicolon=false; + +    /** +    * init the shell and change if readline support is available +    */ +    public function __construct() { +        $this->code = ''; + +        $this->stdin = null; + +        $this->have_readline = function_exists('readline'); + +        if ($this->have_readline) { +            readline_completion_function('__shell_readline_complete'); +        } + +        $this->use_readline = true; + +        $cmd = PHP_Shell_Commands::getInstance(); + +        $cmd->registerCommand('#^quit$#', $this, 'cmdQuit', 'quit', 'leaves the shell'); +        $cmd->registerCommand('#^\?$#', $this, 'cmdHelp', '?', 'show this help'); +        $cmd->registerCommand('#^\?\s+license$#', $this, 'cmdLicense', '? license', 'show license of the shell'); +    } + + +    /** +    * parse the PHP code +    * +    * we parse before we eval() the code to +    * - fetch fatal errors before they come up +    * - know about where we have to wait for closing braces +    * +    * @return int 0 if a executable statement is in the code-buffer, non-zero otherwise +    */ +    public function parse() { +        ## remove empty lines +        if (trim($this->code) == '') return 1; + +        $t = token_get_all('<?php '.$this->code.' ?>'); + +        $need_semicolon = 1; /* do we need a semicolon to complete the statement ? */ +        $need_return = 1;    /* can we prepend a return to the eval-string ? */ +        $open_comment = 0;   /* a open multi-line comment */ +        $eval = '';          /* code to be eval()'ed later */ +        $braces = array();   /* to track if we need more closing braces */ + +        $methods = array();  /* to track duplicate methods in a class declaration */ +        $ts = array();       /* tokens without whitespaces */ + +        foreach ($t as $ndx => $token) { +            if (is_array($token)) { +                $ignore = 0; + +                switch($token[0]) { +                case T_WHITESPACE: +                case T_OPEN_TAG: +                case T_CLOSE_TAG: +                    $ignore = 1; +                    break; +                case T_FOREACH: +                case T_DO: +                case T_WHILE: +                case T_FOR: + +                case T_IF: +                case T_RETURN: + +                case T_CLASS: +                case T_FUNCTION: +                case T_INTERFACE: + +                case T_PRINT: +                case T_ECHO: + +                case T_COMMENT: +                case T_UNSET: + +                case T_INCLUDE: +                case T_REQUIRE: +                case T_INCLUDE_ONCE: +                case T_REQUIRE_ONCE: +                case T_TRY: +                case T_SWITCH: +                case T_DEFAULT: +                case T_CASE: +                case T_BREAK: +                case T_DOC_COMMENT: +                    $need_return = 0; +                    break; +                case T_EMPTY: +                case T_ISSET: +                case T_EVAL: +                case T_EXIT: + +                case T_VARIABLE: +                case T_STRING: +                case T_NEW: +                case T_EXTENDS: +                case T_IMPLEMENTS: +                case T_OBJECT_OPERATOR: +                case T_DOUBLE_COLON: +                case T_INSTANCEOF: + +                case T_CATCH: +                case T_THROW: + +                case T_ELSE: +                case T_AS: +                case T_LNUMBER: +                case T_DNUMBER: +                case T_CONSTANT_ENCAPSED_STRING: +                case T_ENCAPSED_AND_WHITESPACE: +                case T_CHARACTER: +                case T_ARRAY: +                case T_DOUBLE_ARROW: + +                case T_CONST: +                case T_PUBLIC: +                case T_PROTECTED: +                case T_PRIVATE: +                case T_ABSTRACT: +                case T_STATIC: +                case T_VAR: + +                case T_INC: +                case T_DEC: +                case T_SL: +                case T_SL_EQUAL: +                case T_SR: +                case T_SR_EQUAL: + +                case T_IS_EQUAL: +                case T_IS_IDENTICAL: +                case T_IS_GREATER_OR_EQUAL: +                case T_IS_SMALLER_OR_EQUAL: + +                case T_BOOLEAN_OR: +                case T_LOGICAL_OR: +                case T_BOOLEAN_AND: +                case T_LOGICAL_AND: +                case T_LOGICAL_XOR: +                case T_MINUS_EQUAL: +                case T_PLUS_EQUAL: +                case T_MUL_EQUAL: +                case T_DIV_EQUAL: +                case T_MOD_EQUAL: +                case T_XOR_EQUAL: +                case T_AND_EQUAL: +                case T_OR_EQUAL: + +                case T_FUNC_C: +                case T_CLASS_C: +                case T_LINE: +                case T_FILE: + +                case T_BOOL_CAST: +                case T_INT_CAST: +                case T_STRING_CAST: + +                    /* just go on */ +                    break; +                default: +                    /* debug unknown tags*/ +                    error_log(sprintf("unknown tag: %d (%s): %s".PHP_EOL, $token[0], token_name($token[0]), $token[1])); + +                    break; +                } +                if (!$ignore) { +                    $eval .= $token[1]." "; +                    $ts[] = array("token" => $token[0], "value" => $token[1]); +                } +            } else { +                $ts[] = array("token" => $token, "value" => ''); + +                $last = count($ts) - 1; + +                switch ($token) { +                case '(': +                    /* walk backwards through the tokens */ + +                    if ($last >= 4 && +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR && +                        $ts[$last - 3]['token'] == ')' ) { +                        /* func()->method() +                        * +                        * we can't know what func() is return, so we can't +                        * say if the method() exists or not +                        * +                        */ +                    } else if ($last >= 3 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */ +                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR && +                        $ts[$last - 3]['token'] == T_VARIABLE ) { + +                        /* $object->method( */ + +                        /* catch (Exception $e) does not set $e in $GLOBALS[] */ +                        $in_catch = 0; + +                        foreach ($ts as $v) { +                            if ($v['token'] == T_CATCH) { +                                $in_catch = 1; +                            } +                        } + +                        if (!$in_catch) { +                            /* $object has to exist and has to be a object */ +                            $objname = $ts[$last - 3]['value']; + +                            if (!isset($GLOBALS[ltrim($objname, '$')])) { +                                throw new Exception(sprintf('Variable \'%s\' is not set', $objname)); +                            } +                            $object = $GLOBALS[ltrim($objname, '$')]; + +                            if (!is_object($object)) { +                                throw new Exception(sprintf('Variable \'%s\' is not a class', $objname)); +                            } + +                            $method = $ts[$last - 1]['value']; + +                            /* obj */ + +                            if (!method_exists($object, $method)) { +                                throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", +                                    $objname, get_class($object), $method)); +                            } +                        } +                    } else if ($last >= 3 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_VARIABLE && +                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR && +                        $ts[$last - 3]['token'] == T_VARIABLE ) { + +                        /* $object->$method( */ + +                        /* $object has to exist and has to be a object */ +                        $objname = $ts[$last - 3]['value']; + +                        if (!isset($GLOBALS[ltrim($objname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname)); +                        } +                        $object = $GLOBALS[ltrim($objname, '$')]; + +                        if (!is_object($object)) { +                            throw new Exception(sprintf('Variable \'%s\' is not a class', $objname)); +                        } + +                        $methodname = $ts[$last - 1]['value']; + +                        if (!isset($GLOBALS[ltrim($methodname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $methodname)); +                        } +                        $method = $GLOBALS[ltrim($methodname, '$')]; + +                        /* obj */ + +                        if (!method_exists($object, $method)) { +                            throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", +                                $objname, get_class($object), $method)); +                        } + +                    } else if ($last >= 6 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_OBJECT_OPERATOR && +                        $ts[$last - 3]['token'] == ']' && +                            /* might be anything as index */ +                        $ts[$last - 5]['token'] == '[' && +                        $ts[$last - 6]['token'] == T_VARIABLE ) { + +                        /* $object[...]->method( */ + +                        /* $object has to exist and has to be a object */ +                        $objname = $ts[$last - 6]['value']; + +                        if (!isset($GLOBALS[ltrim($objname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname)); +                        } +                        $array = $GLOBALS[ltrim($objname, '$')]; + +                        if (!is_array($array)) { +                            throw new Exception(sprintf('Variable \'%s\' is not a array', $objname)); +                        } + +                        $andx = $ts[$last - 4]['value']; + +                        if (!isset($array[$andx])) { +                            throw new Exception(sprintf('%s[\'%s\'] is not set', $objname, $andx)); +                        } + +                        $object = $array[$andx]; + +                        if (!is_object($object)) { +                            throw new Exception(sprintf('Variable \'%s\' is not a class', $objname)); +                        } + +                        $method = $ts[$last - 1]['value']; + +                        /* obj */ + +                        if (!method_exists($object, $method)) { +                            throw new Exception(sprintf("Variable %s (Class '%s') doesn't have a method named '%s'", +                                $objname, get_class($object), $method)); +                        } + +                    } else if ($last >= 3 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_DOUBLE_COLON && +                        $ts[$last - 3]['token'] == T_STRING ) { + +                        /* Class::method() */ + +                        /* $object has to exist and has to be a object */ +                        $classname = $ts[$last - 3]['value']; + +                        if (!class_exists($classname)) { +                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname)); +                        } + +                        $method = $ts[$last - 1]['value']; + +                        if (!in_array($method, get_class_methods($classname))) { +                            throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'", +                                $classname, $method)); +                        } +                    } else if ($last >= 3 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_VARIABLE && +                        $ts[$last - 2]['token'] == T_DOUBLE_COLON && +                        $ts[$last - 3]['token'] == T_STRING ) { + +                        /* $var::method() */ + +                        /* $object has to exist and has to be a object */ +                        $classname = $ts[$last - 3]['value']; + +                        if (!class_exists($classname)) { +                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname)); +                        } + +                        $methodname = $ts[$last - 1]['value']; + +                        if (!isset($GLOBALS[ltrim($methodname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $methodname)); +                        } +                        $method = $GLOBALS[ltrim($methodname, '$')]; + +                        if (!in_array($method, get_class_methods($classname))) { +                            throw new Exception(sprintf("Class '%s' doesn't have a method named '%s'", +                                $classname, $method)); +                        } + +                    } else if ($last >= 2 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_NEW ) { + +                        /* new Class() */ + +                        /* don't care about this in a class ... { ... } */ + +                        $classname = $ts[$last - 1]['value']; + +                        if (!class_exists($classname)) { +                            throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname)); +                        } + +                        $r = new ReflectionClass($classname); + +                        if ($r->isAbstract()) { +                            throw new Exception(sprintf("Can't instantiate abstract Class '%s'", $classname)); +                        } + +                        if (!$r->isInstantiable()) { +                            throw new Exception(sprintf('Class \'%s\' can\'t be instantiated. Is the class abstract ?', $classname)); +                        } + +                    } else if ($last >= 2 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_FUNCTION ) { + +                        /* make sure we are not a in class definition */ + +                        /* function a() */ + +                        $func = $ts[$last - 1]['value']; + +                        if (function_exists($func)) { +                            throw new Exception(sprintf('Function \'%s\' is already defined', $func)); +                        } +                    } else if ($last >= 4 && +                        $ts[0]['token'] == T_CLASS && +                        $ts[1]['token'] == T_STRING && +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_FUNCTION ) { + +                        /* make sure we are not a in class definition */ + +                        /* class a { .. function a() ... } */ + +                        $func = $ts[$last - 1]['value']; +                        $classname = $ts[1]['value']; + +                        if (isset($methods[$func])) { +                            throw new Exception(sprintf("Can't redeclare method '%s' in Class '%s'", $func, $classname)); +                        } + +                        $methods[$func] = 1; + +                    } else if ($last >= 1 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */ +                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_STRING ) { +                        /* func() */ +                        $funcname = $ts[$last - 1]['value']; + +                        if (!function_exists($funcname)) { +                            throw new Exception(sprintf("Function %s() doesn't exist", $funcname)); +                        } +                    } else if ($last >= 1 && +                        $ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_VARIABLE ) { + +                        /* $object has to exist and has to be a object */ +                        $funcname = $ts[$last - 1]['value']; + +                        if (!isset($GLOBALS[ltrim($funcname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $funcname)); +                        } +                        $func = $GLOBALS[ltrim($funcname, '$')]; + +                        if (!function_exists($func)) { +                            throw new Exception(sprintf("Function %s() doesn't exist", $func)); +                        } + +                    } + +                    array_push($braces, $token); +                    break; +                case '{': +                    $need_return = 0; + +                    if ($last >= 2 && +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_CLASS ) { + +                        /* class name { */ + +                        $classname = $ts[$last - 1]['value']; + +                        if (class_exists($classname, false)) { +                            throw new Exception(sprintf("Class '%s' can't be redeclared", $classname)); +                        } +                    } else if ($last >= 4 && +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_EXTENDS && +                        $ts[$last - 3]['token'] == T_STRING && +                        $ts[$last - 4]['token'] == T_CLASS ) { + +                        /* class classname extends classname { */ + +                        $classname = $ts[$last - 3]['value']; +                        $extendsname = $ts[$last - 1]['value']; + +                        if (class_exists($classname, false)) { +                            throw new Exception(sprintf("Class '%s' can't be redeclared", +                                $classname)); +                        } +                        if (!class_exists($extendsname, true)) { +                            throw new Exception(sprintf("Can't extend '%s' ... from not existing Class '%s'", +                                $classname, $extendsname)); +                        } +                    } else if ($last >= 4 && +                        $ts[$last - 1]['token'] == T_STRING && +                        $ts[$last - 2]['token'] == T_IMPLEMENTS && +                        $ts[$last - 3]['token'] == T_STRING && +                        $ts[$last - 4]['token'] == T_CLASS ) { + +                        /* class name implements interface { */ + +                        $classname = $ts[$last - 3]['value']; +                        $implements = $ts[$last - 1]['value']; + +                        if (class_exists($classname, false)) { +                            throw new Exception(sprintf("Class '%s' can't be redeclared", +                                $classname)); +                        } +                        if (!interface_exists($implements, false)) { +                            throw new Exception(sprintf("Can't implement not existing Interface '%s' for Class '%s'", +                                $implements, $classname)); +                        } +                    } + +                    array_push($braces, $token); +                    break; +                case '}': +                    $need_return = 0; +                case ')': +                    array_pop($braces); +                    break; +                case '[': +                    if ($ts[0]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[0]['token'] != T_ABSTRACT && /* if we are not in a class definition */ +                        $ts[1]['token'] != T_CLASS && /* if we are not in a class definition */ +                        $ts[$last - 1]['token'] == T_VARIABLE) { +                        /* $a[] only works on array and string */ + +                        /* $object has to exist and has to be a object */ +                        $objname = $ts[$last - 1]['value']; + +                        if (!isset($GLOBALS[ltrim($objname, '$')])) { +                            throw new Exception(sprintf('Variable \'%s\' is not set', $objname)); +                        } +                        $obj = $GLOBALS[ltrim($objname, '$')]; + +                        if (is_object($obj)) { +                            throw new Exception(sprintf('Objects (%s) don\'t support array access operators', $objname)); +                        } +                    } +                    break; +                } + +                $eval .= $token; +            } +        } + +        $last = count($ts) - 1; +        if ($last >= 2 && +            $ts[$last - 0]['token'] == T_STRING && +            $ts[$last - 1]['token'] == T_DOUBLE_COLON && +            $ts[$last - 2]['token'] == T_STRING ) { + +            /* Class::constant */ + +            /* $object has to exist and has to be a object */ +            $classname = $ts[$last - 2]['value']; + +            if (!class_exists($classname)) { +                throw new Exception(sprintf('Class \'%s\' doesn\'t exist', $classname)); +            } + +            $constname = $ts[$last - 0]['value']; + +            $c = new ReflectionClass($classname); +            if (!$c->hasConstant($constname)) { +                throw new Exception(sprintf("Class '%s' doesn't have a constant named '%s'", +                    $classname, $constname)); +            } +        } else if ($last == 0 && +            $ts[$last - 0]['token'] == T_VARIABLE ) { + +            /* $var */ + +            $varname = $ts[$last - 0]['value']; + +            if (!isset($GLOBALS[ltrim($varname, '$')])) { +                throw new Exception(sprintf('Variable \'%s\' is not set', $varname)); +            } +        } + + +        $need_more = (count($braces) > 0) || $open_comment; + +        if ($need_more || ';' === $token) { +			$need_semicolon = 0; +        } + +        if ($need_return) { +            $eval = "return ".$eval; +        } + +        /* add a traling ; if necessary */ +        if ($need_semicolon) +		{ +			$this->has_semicolon = preg_match('/;\s*$/', $eval); +			$eval .= ';'; +		} + +        if (!$need_more) { +            $this->code = $eval; +        } + +        return $need_more; +    } + +    /** +    * show the prompt and fetch a single line +    * +    * uses readline() if avaialbe +    * +    * @return string a input-line +    */ +    public function readline() { +        if (empty($this->code)) print PHP_EOL; + +        $prompt = (empty($this->code)) ? '>> ' : '.. '; + +        if (count($this->code_buffer) > 0) { +            print $prompt; + +            $line = array_shift($this->code_buffer); + +            print $line.PHP_EOL; + +            return $line.PHP_EOL; +        } + +        if ($this->have_readline) { +            $l = readline($prompt); + +            readline_add_history($l); +        } else { +            print $prompt; + +            if (is_null($this->stdin)) { +                if (false === ($this->stdin = fopen("php://stdin", "r"))) { +                    return false; +                } +            } +            $l = fgets($this->stdin); +        } +        return $l; +    } + +    /** +    * get the inline help +    * +    * @return string the inline help as string +    */ +    public function cmdHelp($l) { +        $o = 'Inline Help:'.PHP_EOL; + +        $cmds = PHP_Shell_Commands::getInstance()->getCommands(); + +        $help = array(); +        foreach ($cmds as $cmd) { +            $help[] = sprintf('  >> %s'.PHP_EOL.'    %s'.PHP_EOL, +                $cmd['command'], +                $cmd['description'] +            ); +        } + +        return var_export(implode("\n", $help), 1); +    } + +    /** +    * get the license string +    * +    * @return string the inline help as string +    */ +    public function cmdLicense($l) { +        $o = <<<EOF +(c) 2006 Jan Kneschke <jan@kneschke.de> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +EOF; + +        return var_export($o, 1); +    } + +    /** +    * handle the 'quit' command +    * +    * @return bool false to leave the input() call +    * @see input +    */ +    protected function cmdQuit($l) { +        return false; +    } + +    /** +    * handle the input line +    * +    * read the input and handle the commands of the shell +    * +    * @return bool false on 'quit' or EOF, true otherwise +    */ +    public function input() { +        $l = $this->readline(); + +        /* got EOF ? */ +        if (false === $l) return false; + +        $l = trim($l); + +        if (empty($this->code)) { +            $this->verbose = 0; + +            $cmds = PHP_Shell_Commands::getInstance()->getCommands(); + +            foreach ($cmds as $cmd) { +                if (preg_match($cmd['regex'], $l)) { +                    $obj = $cmd['obj']; +                    $func = $cmd['method']; + +                    if (false === ($l = $obj->$func($l))) { +                        ## quit +                        return false; +                    } + +                    if (is_array($l)) { +                        $this->code_buffer = $l; +                        $l = ''; +                    } +                    break; +                } +            } +        } + +        $this->appendCode($l); + +        return true; +    } + +    /** +    * get the code-buffer +    * +    * @return string the code-buffer +    */ +    public function getCode() { +		return $this->code; +        return $code; +    } + +    /** +    * reset the code-buffer +    */ +    public function resetCode() { +		$this->has_semicolon=false; +        $this->code = ''; +    } + +    /** +    * append code to the code-buffer +    * +    * @param string $code input buffer +    */ +    public function appendCode($code) { +        if (strlen($code)) $code .= PHP_EOL; + +        $this->code .= $code; +    } + +    /** +    * check if readline support is enabled +    * +    * @return bool true if enabled, false otherwise +    */ +    public function hasReadline() { +        return $this->have_readline; +    } + +    /** +    * get version of the class +    * +    * @return string version-string +    */ +    public function getVersion() { +        return $this->version; +    } +} + +/** +* a readline completion callback +* +* @param string $str linebuffer +* @param integer $pos position in linebuffer +* @return array list of possible matches +*/ +function __shell_readline_complete($str, $pos) { +    $in = readline_info('line_buffer'); + +    /** +    * parse the line-buffer backwards to see if we have a +    * - constant +    * - function +    * - variable +    */ + +    $m = array(); + +    if (preg_match('#\$([A-Za-z0-9_]+)->#', $in, $a)) { +        /* check for $o->... */ +        $name = $a[1]; + +        if (isset($GLOBALS[$name]) && is_object($GLOBALS[$name])) { +            $c = get_class_methods($GLOBALS[$name]); + +            foreach ($c as $v) { +                $m[] = $v.'('; +            } +            $c = get_class_vars(get_class($GLOBALS[$name])); + +            foreach ($c as $k => $v) { +                $m[] = $k; +            } + +            return $m; +        } +    } else if (preg_match('#\$([A-Za-z0-9_]+)\[([^\]]+)\]->#', $in, $a)) { +        /* check for $o[...]->... */ +        $name = $a[1]; + +        if (isset($GLOBALS[$name]) && +            is_array($GLOBALS[$name]) && +            isset($GLOBALS[$name][$a[2]])) { + +            $c = get_class_methods($GLOBALS[$name][$a[2]]); + +            foreach ($c as $v) { +                $m[] = $v.'('; +            } +            $c = get_class_vars(get_class($GLOBALS[$name][$a[2]])); + +            foreach ($c as $k => $v) { +                $m[] = $k; +            } +            return $m; +        } + +    } else if (preg_match('#([A-Za-z0-9_]+)::#', $in, $a)) { +        /* check for Class:: */ +        $name = $a[1]; + +        if (class_exists($name, false)) { +            $c = get_class_methods($name); + +            foreach ($c as $v) { +                $m[] = sprintf('%s::%s(', $name, $v); +            } + +            $cl = new ReflectionClass($name); +            $c = $cl->getConstants(); + +            foreach ($c as $k => $v) { +                $m[] = sprintf('%s::%s', $name, $k); +            } + +            return $m; +        } +    } else if (preg_match('#\$([a-zA-Z]?[a-zA-Z0-9_]*)$#', $in)) { +        $m = array_keys($GLOBALS); + +        return $m; +    } else if (preg_match('#new #', $in)) { +        $c = get_declared_classes(); + +        foreach ($c as $v) { +            $m[] = $v.'('; +        } + +        return $m; +    } else if (preg_match('#^:set #', $in)) { +        foreach (PHP_Shell_Options::getInstance()->getOptions() as $v) { +            $m[] = $v; +        } + +        return $m; +    } + +    $f = get_defined_functions(); + +    foreach ($f['internal'] as $v) { +        $m[] = $v.'('; +    } + +    foreach ($f['user'] as $v) { +        $m[] = $v.'('; +    } + +    $c = get_declared_classes(); + +    foreach ($c as $v) { +        $m[] = $v.'::'; +    } + +    $c = get_defined_constants(); + +    foreach ($c as $k => $v) { +        $m[] = $k; +    } + +    /* taken from http://de3.php.net/manual/en/reserved.php */ +    $m[] = 'abstract'; +    $m[] = 'and'; +    $m[] = 'array('; +    $m[] = 'as'; +    $m[] = 'break'; +    $m[] = 'case'; +    $m[] = 'catch'; +    $m[] = 'class'; +    $m[] = 'const'; +    $m[] = 'continue'; +    # $m[] = 'declare'; +    $m[] = 'default'; +    $m[] = 'die('; +    $m[] = 'do'; +    $m[] = 'echo('; +    $m[] = 'else'; +    $m[] = 'elseif'; +    $m[] = 'empty('; +    # $m[] = 'enddeclare'; +    $m[] = 'eval('; +    $m[] = 'exception'; +    $m[] = 'extends'; +    $m[] = 'exit('; +    $m[] = 'extends'; +    $m[] = 'final'; +    $m[] = 'for ('; +    $m[] = 'foreach ('; +    $m[] = 'function'; +    $m[] = 'global'; +    $m[] = 'if'; +    $m[] = 'implements'; +    $m[] = 'include "'; +    $m[] = 'include_once "'; +    $m[] = 'interface'; +    $m[] = 'isset('; +    $m[] = 'list('; +    $m[] = 'new'; +    $m[] = 'or'; +    $m[] = 'print('; +    $m[] = 'private'; +    $m[] = 'protected'; +    $m[] = 'public'; +    $m[] = 'require "'; +    $m[] = 'require_once "'; +    $m[] = 'return'; +    $m[] = 'static'; +    $m[] = 'switch ('; +    $m[] = 'throw'; +    $m[] = 'try'; +    $m[] = 'unset('; +    # $m[] = 'use'; +    $m[] = 'var'; +    $m[] = 'while'; +    $m[] = 'xor'; +    $m[] = '__FILE__'; +    $m[] = '__FUNCTION__'; +    $m[] = '__CLASS__'; +    $m[] = '__LINE__'; +    $m[] = '__METHOD__'; + +    # printf("%s ... %s\n", $str, $pos); +    return $m; +} + +  | 
