xref: /PHP-8.2/sapi/phpdbg/phpdbg_set.c (revision 60fbd6df)
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    | https://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(break,        "usage: set break id [<on|off>]",          'b', set_break,        NULL, "l|b", PHPDBG_ASYNC_SAFE),
39 	PHPDBG_SET_COMMAND_D(breaks,       "usage: set breaks [<on|off>]",            'B', set_breaks,       NULL, "|b", PHPDBG_ASYNC_SAFE),
40 	PHPDBG_SET_COMMAND_D(quiet,        "usage: set quiet [<on|off>]",             'q', set_quiet,        NULL, "|b", PHPDBG_ASYNC_SAFE),
41 	PHPDBG_SET_COMMAND_D(stepping,     "usage: set stepping [<line|op>]",         's', set_stepping,     NULL, "|s", PHPDBG_ASYNC_SAFE),
42 	PHPDBG_SET_COMMAND_D(refcount,     "usage: set refcount [<on|off>]",          'r', set_refcount,     NULL, "|b", PHPDBG_ASYNC_SAFE),
43 	PHPDBG_SET_COMMAND_D(lines,        "usage: set lines [<number>]",             'l', set_lines,        NULL, "|l", PHPDBG_ASYNC_SAFE),
44 	PHPDBG_END_COMMAND
45 };
46 
PHPDBG_SET(prompt)47 PHPDBG_SET(prompt) /* {{{ */
48 {
49 	if (!param || param->type == EMPTY_PARAM) {
50 		phpdbg_writeln("Current prompt: %s", phpdbg_get_prompt());
51 	} else {
52 		phpdbg_set_prompt(param->str);
53 	}
54 
55 	return SUCCESS;
56 } /* }}} */
57 
PHPDBG_SET(pagination)58 PHPDBG_SET(pagination) /* {{{ */
59 {
60 	if (!param || param->type == EMPTY_PARAM) {
61 		phpdbg_writeln("Pagination %s", PHPDBG_G(flags) & PHPDBG_HAS_PAGINATION ? "on" : "off");
62 	} else switch (param->type) {
63 		case NUMERIC_PARAM: {
64 			if (param->num) {
65 				PHPDBG_G(flags) |= PHPDBG_HAS_PAGINATION;
66 			} else {
67 				PHPDBG_G(flags) &= ~PHPDBG_HAS_PAGINATION;
68 			}
69 		} break;
70 
71 		default:
72 			phpdbg_error("set pagination used incorrectly: set pagination <on|off>");
73 	}
74 
75 	return SUCCESS;
76 } /* }}} */
77 
PHPDBG_SET(lines)78 PHPDBG_SET(lines) /* {{{ */
79 {
80 	if (!param || param->type == EMPTY_PARAM) {
81 		phpdbg_writeln("Lines "ZEND_ULONG_FMT, PHPDBG_G(lines));
82 	} else switch (param->type) {
83 		case NUMERIC_PARAM: {
84 			PHPDBG_G(lines) = param->num;
85 		} break;
86 
87 		default:
88 			phpdbg_error("set lines used incorrectly: set lines <number>");
89 	}
90 
91 	return SUCCESS;
92 } /* }}} */
93 
PHPDBG_SET(break)94 PHPDBG_SET(break) /* {{{ */
95 {
96 	switch (param->type) {
97 		case NUMERIC_PARAM: {
98 			if (param->next) {
99 				if (param->next->num) {
100 					phpdbg_enable_breakpoint(param->num);
101 				} else {
102 					phpdbg_disable_breakpoint(param->num);
103 				}
104 			} else {
105 				phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num);
106 				if (brake) {
107 					phpdbg_writeln("Breakpoint #"ZEND_LONG_FMT" %s", param->num, brake->disabled ? "off" : "on");
108 				} else {
109 					phpdbg_error("Failed to find breakpoint #"ZEND_LONG_FMT, param->num);
110 				}
111 			}
112 		} break;
113 
114 		default:
115 			phpdbg_error("set break used incorrectly: set break [id] <on|off>");
116 	}
117 
118 	return SUCCESS;
119 } /* }}} */
120 
PHPDBG_SET(breaks)121 PHPDBG_SET(breaks) /* {{{ */
122 {
123 	if (!param || param->type == EMPTY_PARAM) {
124 		phpdbg_writeln("Breakpoints %s",PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off");
125 	} else switch (param->type) {
126 		case NUMERIC_PARAM: {
127 			if (param->num) {
128 				phpdbg_enable_breakpoints();
129 			} else {
130 				phpdbg_disable_breakpoints();
131 			}
132 		} break;
133 
134 		default:
135 			phpdbg_error("set breaks used incorrectly: set breaks <on|off>");
136 	}
137 
138 	return SUCCESS;
139 } /* }}} */
140 
141 #ifndef _WIN32
PHPDBG_SET(color)142 PHPDBG_SET(color) /* {{{ */
143 {
144 	const phpdbg_color_t *color = phpdbg_get_color(param->next->str, param->next->len);
145 
146 	if (!color) {
147 		phpdbg_error("Failed to find the requested color (%s)", param->next->str);
148 		return SUCCESS;
149 	}
150 
151 	switch (phpdbg_get_element(param->str, param->len)) {
152 		case PHPDBG_COLOR_PROMPT:
153 			phpdbg_notice("setting prompt color to %s (%s)", color->name, color->code);
154 			if (PHPDBG_G(prompt)[1]) {
155 				free(PHPDBG_G(prompt)[1]);
156 				PHPDBG_G(prompt)[1]=NULL;
157 			}
158 			phpdbg_set_color(PHPDBG_COLOR_PROMPT, color);
159 		break;
160 
161 		case PHPDBG_COLOR_ERROR:
162 			phpdbg_notice("setting error color to %s (%s)", color->name, color->code);
163 			phpdbg_set_color(PHPDBG_COLOR_ERROR, color);
164 		break;
165 
166 		case PHPDBG_COLOR_NOTICE:
167 			phpdbg_notice("setting notice color to %s (%s)", color->name, color->code);
168 			phpdbg_set_color(PHPDBG_COLOR_NOTICE, color);
169 		break;
170 
171 		default:
172 			phpdbg_error("Failed to find the requested element (%s)", param->str);
173 	}
174 
175 	return SUCCESS;
176 } /* }}} */
177 
PHPDBG_SET(colors)178 PHPDBG_SET(colors) /* {{{ */
179 {
180 	if (!param || param->type == EMPTY_PARAM) {
181 		phpdbg_writeln("Colors %s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off");
182 	} else switch (param->type) {
183 		case NUMERIC_PARAM: {
184 			if (param->num) {
185 				PHPDBG_G(flags) |= PHPDBG_IS_COLOURED;
186 			} else {
187 				PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED;
188 			}
189 		} break;
190 
191 		default:
192 			phpdbg_error("set colors used incorrectly: set colors <on|off>");
193 	}
194 
195 	return SUCCESS;
196 } /* }}} */
197 #endif
198 
PHPDBG_SET(quiet)199 PHPDBG_SET(quiet) /* {{{ */
200 {
201 	if (!param || param->type == EMPTY_PARAM) {
202 		phpdbg_writeln("Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
203 	} else switch (param->type) {
204 		case NUMERIC_PARAM: {
205 			if (param->num) {
206 				PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
207 			} else {
208 				PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
209 			}
210 		} break;
211 
212 		phpdbg_default_switch_case();
213 	}
214 
215 	return SUCCESS;
216 } /* }}} */
217 
PHPDBG_SET(stepping)218 PHPDBG_SET(stepping) /* {{{ */
219 {
220 	if (!param || param->type == EMPTY_PARAM) {
221 		phpdbg_writeln("Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line");
222 	} else switch (param->type) {
223 		case STR_PARAM: {
224 			if (param->len == sizeof("opcode") - 1 && !memcmp(param->str, "opcode", sizeof("opcode"))) {
225 				PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE;
226 			} else if (param->len == sizeof("line") - 1 && !memcmp(param->str, "line", sizeof("line"))) {
227 				PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE;
228 			} else {
229 				phpdbg_error("usage set stepping [<opcode|line>]");
230 			}
231 		} break;
232 
233 		phpdbg_default_switch_case();
234 	}
235 
236 	return SUCCESS;
237 } /* }}} */
238 
PHPDBG_SET(refcount)239 PHPDBG_SET(refcount) /* {{{ */
240 {
241 	if (!param || param->type == EMPTY_PARAM) {
242 		phpdbg_writeln("Showing refcounts %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
243 	} else switch (param->type) {
244 		case NUMERIC_PARAM: {
245 			if (param->num) {
246 				PHPDBG_G(flags) |= PHPDBG_SHOW_REFCOUNTS;
247 			} else {
248 				PHPDBG_G(flags) &= ~PHPDBG_SHOW_REFCOUNTS;
249 			}
250 		} break;
251 
252 		phpdbg_default_switch_case();
253 	}
254 
255 	return SUCCESS;
256 } /* }}} */
257