1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Felipe Pena <felipe@php.net> |
16 | Authors: Joe Watkins <joe.watkins@live.co.uk> |
17 | Authors: Bob Weinand <bwoebi@php.net> |
18 +----------------------------------------------------------------------+
19 */
20
21 #include "phpdbg.h"
22 #include "phpdbg_cmd.h"
23 #include "phpdbg_set.h"
24 #include "phpdbg_utils.h"
25 #include "phpdbg_bp.h"
26 #include "phpdbg_prompt.h"
27
28 ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
29
30 #define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s, flags) \
31 PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[17], flags)
32
33 const phpdbg_command_t phpdbg_set_commands[] = {
34 PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s", 0),
35 PHPDBG_SET_COMMAND_D(pagination, "usage: set pagination [<on|off>]", 'P', set_pagination, NULL, "|b", PHPDBG_ASYNC_SAFE),
36 #ifndef _WIN32
37 PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss", PHPDBG_ASYNC_SAFE),
38 PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b", PHPDBG_ASYNC_SAFE),
39 #endif
40 PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog [<output>]", 'O', set_oplog, NULL, "|s", 0),
41 PHPDBG_SET_COMMAND_D(break, "usage: set break id [<on|off>]", 'b', set_break, NULL, "l|b", PHPDBG_ASYNC_SAFE),
42 PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks [<on|off>]", 'B', set_breaks, NULL, "|b", PHPDBG_ASYNC_SAFE),
43 PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b", PHPDBG_ASYNC_SAFE),
44 PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping [<line|op>]", 's', set_stepping, NULL, "|s", PHPDBG_ASYNC_SAFE),
45 PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b", PHPDBG_ASYNC_SAFE),
46 PHPDBG_SET_COMMAND_D(lines, "usage: set lines [<number>]", 'l', set_lines, NULL, "|l", PHPDBG_ASYNC_SAFE),
47 PHPDBG_END_COMMAND
48 };
49
PHPDBG_SET(prompt)50 PHPDBG_SET(prompt) /* {{{ */
51 {
52 if (!param || param->type == EMPTY_PARAM) {
53 phpdbg_writeln("setprompt", "str=\"%s\"", "Current prompt: %s", phpdbg_get_prompt());
54 } else {
55 phpdbg_set_prompt(param->str);
56 }
57
58 return SUCCESS;
59 } /* }}} */
60
PHPDBG_SET(pagination)61 PHPDBG_SET(pagination) /* {{{ */
62 {
63 if (!param || param->type == EMPTY_PARAM) {
64 phpdbg_writeln("setpagination", "active=\"%s\"", "Pagination %s", PHPDBG_G(flags) & PHPDBG_HAS_PAGINATION ? "on" : "off");
65 } else switch (param->type) {
66 case NUMERIC_PARAM: {
67 if (param->num) {
68 PHPDBG_G(flags) |= PHPDBG_HAS_PAGINATION;
69 } else {
70 PHPDBG_G(flags) &= ~PHPDBG_HAS_PAGINATION;
71 }
72 } break;
73
74 default:
75 phpdbg_error("setpagination", "type=\"wrongargs\"", "set pagination used incorrectly: set pagination <on|off>");
76 }
77
78 return SUCCESS;
79 } /* }}} */
80
PHPDBG_SET(lines)81 PHPDBG_SET(lines) /* {{{ */
82 {
83 if (!param || param->type == EMPTY_PARAM) {
84 phpdbg_writeln("setlines", "active=\"%s\"", "Lines %ld", PHPDBG_G(lines));
85 } else switch (param->type) {
86 case NUMERIC_PARAM: {
87 PHPDBG_G(lines) = param->num;
88 } break;
89
90 default:
91 phpdbg_error("setlines", "type=\"wrongargs\"", "set lines used incorrectly: set lines <number>");
92 }
93
94 return SUCCESS;
95 } /* }}} */
96
PHPDBG_SET(break)97 PHPDBG_SET(break) /* {{{ */
98 {
99 switch (param->type) {
100 case NUMERIC_PARAM: {
101 if (param->next) {
102 if (param->next->num) {
103 phpdbg_enable_breakpoint(param->num);
104 } else {
105 phpdbg_disable_breakpoint(param->num);
106 }
107 } else {
108 phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num);
109 if (brake) {
110 phpdbg_writeln("setbreak", "id=\"%ld\" active=\"%s\"", "Breakpoint #%ld %s", param->num, brake->disabled ? "off" : "on");
111 } else {
112 phpdbg_error("setbreak", "type=\"nobreak\" id=\"%ld\"", "Failed to find breakpoint #%ld", param->num);
113 }
114 }
115 } break;
116
117 default:
118 phpdbg_error("setbreak", "type=\"wrongargs\"", "set break used incorrectly: set break [id] <on|off>");
119 }
120
121 return SUCCESS;
122 } /* }}} */
123
PHPDBG_SET(breaks)124 PHPDBG_SET(breaks) /* {{{ */
125 {
126 if (!param || param->type == EMPTY_PARAM) {
127 phpdbg_writeln("setbreaks", "active=\"%s\"", "Breakpoints %s",PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off");
128 } else switch (param->type) {
129 case NUMERIC_PARAM: {
130 if (param->num) {
131 phpdbg_enable_breakpoints();
132 } else {
133 phpdbg_disable_breakpoints();
134 }
135 } break;
136
137 default:
138 phpdbg_error("setbreaks", "type=\"wrongargs\"", "set breaks used incorrectly: set breaks <on|off>");
139 }
140
141 return SUCCESS;
142 } /* }}} */
143
144 #ifndef _WIN32
PHPDBG_SET(color)145 PHPDBG_SET(color) /* {{{ */
146 {
147 const phpdbg_color_t *color = phpdbg_get_color(param->next->str, param->next->len);
148
149 if (!color) {
150 phpdbg_error("setcolor", "type=\"nocolor\"", "Failed to find the requested color (%s)", param->next->str);
151 return SUCCESS;
152 }
153
154 switch (phpdbg_get_element(param->str, param->len)) {
155 case PHPDBG_COLOR_PROMPT:
156 phpdbg_notice("setcolor", "type=\"prompt\" color=\"%s\" code=\"%s\"", "setting prompt color to %s (%s)", color->name, color->code);
157 if (PHPDBG_G(prompt)[1]) {
158 free(PHPDBG_G(prompt)[1]);
159 PHPDBG_G(prompt)[1]=NULL;
160 }
161 phpdbg_set_color(PHPDBG_COLOR_PROMPT, color);
162 break;
163
164 case PHPDBG_COLOR_ERROR:
165 phpdbg_notice("setcolor", "type=\"error\" color=\"%s\" code=\"%s\"", "setting error color to %s (%s)", color->name, color->code);
166 phpdbg_set_color(PHPDBG_COLOR_ERROR, color);
167 break;
168
169 case PHPDBG_COLOR_NOTICE:
170 phpdbg_notice("setcolor", "type=\"notice\" color=\"%s\" code=\"%s\"", "setting notice color to %s (%s)", color->name, color->code);
171 phpdbg_set_color(PHPDBG_COLOR_NOTICE, color);
172 break;
173
174 default:
175 phpdbg_error("setcolor", "type=\"invalidtype\"", "Failed to find the requested element (%s)", param->str);
176 }
177
178 return SUCCESS;
179 } /* }}} */
180
PHPDBG_SET(colors)181 PHPDBG_SET(colors) /* {{{ */
182 {
183 if (!param || param->type == EMPTY_PARAM) {
184 phpdbg_writeln("setcolors", "active=\"%s\"", "Colors %s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off");
185 } else switch (param->type) {
186 case NUMERIC_PARAM: {
187 if (param->num) {
188 PHPDBG_G(flags) |= PHPDBG_IS_COLOURED;
189 } else {
190 PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED;
191 }
192 } break;
193
194 default:
195 phpdbg_error("setcolors", "type=\"wrongargs\"", "set colors used incorrectly: set colors <on|off>");
196 }
197
198 return SUCCESS;
199 } /* }}} */
200 #endif
201
PHPDBG_SET(oplog)202 PHPDBG_SET(oplog) /* {{{ */
203 {
204 if (!param || param->type == EMPTY_PARAM) {
205 phpdbg_notice("setoplog", "active=\"%s\"", "Oplog %s", PHPDBG_G(oplog) ? "on" : "off");
206 } else switch (param->type) {
207 case STR_PARAM: {
208 /* open oplog */
209 FILE *old = PHPDBG_G(oplog);
210
211 PHPDBG_G(oplog) = fopen(param->str, "w+");
212 if (!PHPDBG_G(oplog)) {
213 phpdbg_error("setoplog", "type=\"openfailure\" file=\"%s\"", "Failed to open %s for oplog", param->str);
214 PHPDBG_G(oplog) = old;
215 } else {
216 if (old) {
217 phpdbg_notice("setoplog", "type=\"closingold\"", "Closing previously open oplog");
218 fclose(old);
219 }
220
221 phpdbg_notice("setoplog", "file=\"%s\"", "Successfully opened oplog %s", param->str);
222 }
223 } break;
224
225 phpdbg_default_switch_case();
226 }
227
228 return SUCCESS;
229 } /* }}} */
230
PHPDBG_SET(quiet)231 PHPDBG_SET(quiet) /* {{{ */
232 {
233 if (!param || param->type == EMPTY_PARAM) {
234 phpdbg_writeln("setquiet", "active=\"%s\"", "Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
235 } else switch (param->type) {
236 case NUMERIC_PARAM: {
237 if (param->num) {
238 PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
239 } else {
240 PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
241 }
242 } break;
243
244 phpdbg_default_switch_case();
245 }
246
247 return SUCCESS;
248 } /* }}} */
249
PHPDBG_SET(stepping)250 PHPDBG_SET(stepping) /* {{{ */
251 {
252 if (!param || param->type == EMPTY_PARAM) {
253 phpdbg_writeln("setstepping", "type=\"%s\"", "Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line");
254 } else switch (param->type) {
255 case STR_PARAM: {
256 if (param->len == sizeof("opcode") - 1 && !memcmp(param->str, "opcode", sizeof("opcode"))) {
257 PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE;
258 } else if (param->len == sizeof("line") - 1 && !memcmp(param->str, "line", sizeof("line"))) {
259 PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE;
260 } else {
261 phpdbg_error("setstepping", "type=\"wrongargs\"", "usage set stepping [<opcode|line>]");
262 }
263 } break;
264
265 phpdbg_default_switch_case();
266 }
267
268 return SUCCESS;
269 } /* }}} */
270
PHPDBG_SET(refcount)271 PHPDBG_SET(refcount) /* {{{ */
272 {
273 if (!param || param->type == EMPTY_PARAM) {
274 phpdbg_writeln("setrefcount", "active=\"%s\"", "Showing refcounts %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
275 } else switch (param->type) {
276 case NUMERIC_PARAM: {
277 if (param->num) {
278 PHPDBG_G(flags) |= PHPDBG_SHOW_REFCOUNTS;
279 } else {
280 PHPDBG_G(flags) &= ~PHPDBG_SHOW_REFCOUNTS;
281 }
282 } break;
283
284 phpdbg_default_switch_case();
285 }
286
287 return SUCCESS;
288 } /* }}} */
289