-
Notifications
You must be signed in to change notification settings - Fork 1
/
phpa-norl
executable file
·245 lines (217 loc) · 7.18 KB
/
phpa-norl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#!/usr/bin/php
<?php
/*
$Id: phpa-norl.php 2010/06/16 $
Stefan Fischerländer <stefan@fischerlaender.de>, http://www.fischerlaender.net/php/phpa-norl
original version: David Phillips <david@acz.org>, http://david.acz.org/phpa/
2010/07/16 - register_shutdown_function
2010/07/16 - now using PHP_EOL
2010/07/16 - replaced deprecated split function
2007/07/10 - CTRL-D now exits the script instead of entering an infinite loop
2007/07/08 - initial version of phpa-norl published
*/
register_shutdown_function('shutdown');
__phpa__setup();
__phpa__print_info();
/*
* begin edit by Stefan Fischerländer
*/
define("__PHPA_HISTORY_COMMAND", 'h'); // defines the command name for history manipulation
define("__PHPA_EXIT_COMMAND", 'q'); // defines the command name to exit the shell
define("__PHPA_MAX_HIST", 20); // maximum number of history entries
define("__PHPA_PROMPT", PHP_VERSION.' > ');
$__phpa_myhist = array();
$__phpa_fh = fopen('php://stdin','rb') or die($php_errormsg);
/*
* end edit by Stefan Fischerländer
*/
for (;;)
{
/*
* begin edit by Stefan Fischerländer
*/
$__phpa_line = myReadLine($__phpa_fh, __PHPA_PROMPT);
if ($__phpa_line == __PHPA_EXIT_COMMAND)
{
echo PHP_EOL;
break;
} elseif( $__phpa_line == __PHPA_HISTORY_COMMAND ) {
showHistory($__phpa_myhist);
continue;
} elseif( preg_match('/^'.__PHPA_HISTORY_COMMAND.'\s*(\d+)$/', $__phpa_line, $__phpa_result) ) {
$__phpa_line = $__phpa_myhist[$__phpa_result[1]];
array_splice($__phpa_myhist, $__phpa_result[1], 1);
echo __PHPA_PROMPT.$__phpa_line.PHP_EOL;
}
if (strlen($__phpa_line) == 0)
continue;
# manage history
array_unshift($__phpa_myhist, $__phpa_line);
if( count($__phpa_myhist) > __PHPA_MAX_HIST )
array_pop($__phpa_myhist);
/*
* end edit by Stefan Fischerländer
*/
if (__phpa__is_immediate($__phpa_line))
$__phpa_line = "return ($__phpa_line)";
ob_start();
$__phpa_ret = eval("unset(\$line); $__phpa_line;");
if (ob_get_length() == 0)
{
if (is_bool($__phpa_ret))
echo ($__phpa_ret ? "true" : "false");
else if (is_string($__phpa_ret))
echo "'" . addcslashes($__phpa_ret, "\0..\37\177..\377") . "'";
else if (!is_null($__phpa_ret))
print_r($__phpa_ret);
}
unset($__phpa_ret);
$__phpa_out = ob_get_contents();
ob_end_clean();
if ((strlen($__phpa_out) > 0) && (substr($__phpa_out, -1) != PHP_EOL))
$__phpa_out .= PHP_EOL;
echo $__phpa_out;
unset($__phpa_out);
}
fclose($__phpa_fh);
/**
*
* @author Stefan Fischerländer
* @return STRING input from keyboard, may contain line breaks
*/
function myReadLine($fh, $prompt)
{
echo $prompt;
$complete_line = '';
for(;;) {
if(function_exists('readline')){
$line = readline('');
}else{
$line = fgets($fh,1024);
}
if( !$line && strlen($line)==0 ) # this is true, when CTRL-D is pressed
die("\nUser pressed CTRL-D. phpa-norl quits.\n");
$line = rtrim($line);
$line = rtrim($line, ';'); // strip last ";"
$complete_line .= $line;
if( substr($line,-1) != '#')
break;
else
$complete_line = substr($complete_line,0,-1).PHP_EOL;
}
return $complete_line;
}
/**
*
* @author Stefan Fischerländer
* @return STRING input from keyboard, may contain line breaks
*/
function showHistory($myhist)
{
echo "History:\n";
for( $i=count($myhist)-1; $i>=0; $i--) {
$val = $myhist[$i];
$prompt = "[$i] => ";
echo $prompt;
if( strpos($val, PHP_EOL) > 0 ) {
echo str_replace("\n", str_pad("\n", strlen($prompt)+1, ' '), str_replace("\t", ' ', $val));
echo "\n";
}
else
echo "$val\n";
}
}
function __phpa__rl_complete($line, $pos, $cursor)
{
$const = array_keys(get_defined_constants());
$var = array_keys($GLOBALS);
$func = get_defined_functions();
$s = "__phpa__";
foreach ($func["user"] as $i)
if (substr($i, 0, strlen($s)) != $s)
$func["internal"][] = $i;
$func = $func["internal"];
return array_merge($const, $var, $func);
}
function __phpa__is_immediate($line)
{
$skip = array("class", "declare", "die", "echo", "exit", "for",
"foreach", "function", "global", "if", "include",
"include_once", "print", "require", "require_once",
"return", "static", "switch", "while");
$okeq = array("===", "!==", "==", "!=", "<=", ">=");
$code = "";
$sq = false;
$dq = false;
for ($i = 0; $i < strlen($line); $i++)
{
$c = $line{$i};
if ($c == "'")
$sq = !$sq;
else if ($c == '"')
$dq = !$dq;
else if (($sq) || ($dq))
{
if ($c == "\\")
$i++;
}
else
$code .= $c;
}
$code = str_replace($okeq, "", $code);
if (strcspn($code, ";{=") != strlen($code))
return false;
$kw = preg_split("/[^A-Za-z0-9_]/", $code);
foreach ($kw as $i)
if (in_array($i, $skip))
return false;
return true;
}
function __phpa__print_info()
{
$ver = phpversion();
$sapi = php_sapi_name();
$date = __phpa__build_date();
$os = PHP_OS;
echo "PHP $ver ($sapi) ($date) [$os]\n";
}
function __phpa__build_date()
{
ob_start();
phpinfo(INFO_GENERAL);
$x = ob_get_contents();
ob_end_clean();
$x = strip_tags($x);
$x = explode(PHP_EOL, $x);
$s = array("Build Date => ", "Build Date ");
foreach ($x as $i)
foreach ($s as $j)
if (substr($i, 0, strlen($j)) == $j)
return trim(substr($i, strlen($j)));
return "???";
}
function __phpa__setup()
{
if (version_compare(phpversion(), "4.3.0", "<"))
{
echo "PHP 4.3.0 or above is required.\n";
exit(111);
}
error_reporting(E_ALL ^ E_NOTICE);
ini_set("html_errors", 0);
while (ob_get_level())
ob_end_clean();
ob_implicit_flush(true);
}
// This is our shutdown function, in
// here we can do any last operations
// before the script is complete.
function shutdown() {
global $gEvalError, $gErrorScript;
if ( $gEvalError ) {
echo PHP_EOL;
echo PHP_EOL;
echo 'eval() error: ' . $gErrorScript, PHP_EOL;
}
}
?>