xref: /PHP-8.0/sapi/phpdbg/phpdbg_set.c (revision 5d6e923d)
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