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