php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
phpdbg_cmd.c
Go to the documentation of this file.
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_utils.h"
22#include "phpdbg_set.h"
23#include "phpdbg_prompt.h"
24#include "phpdbg_io.h"
25
26#ifdef HAVE_UNISTD_H
27# include <unistd.h>
28#endif
29
31
32static inline const char *phpdbg_command_name(const phpdbg_command_t *command, char *buffer) {
33 size_t pos = 0;
34
35 if (command->parent) {
36 memcpy(&buffer[pos], command->parent->name, command->parent->name_len);
37 pos += command->parent->name_len;
38 memcpy(&buffer[pos], " ", sizeof(" ")-1);
39 pos += (sizeof(" ")-1);
40 }
41
42 memcpy(&buffer[pos], command->name, command->name_len);
43 pos += command->name_len;
44 buffer[pos] = 0;
45
46 return buffer;
47}
48
49PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param) /* {{{ */
50{
51 switch (param->type) {
52 case STACK_PARAM:
53 return "stack";
54 case EMPTY_PARAM:
55 return "empty";
56 case ADDR_PARAM:
57 return "address";
58 case NUMERIC_PARAM:
59 return "numeric";
60 case METHOD_PARAM:
61 return "method";
63 return "function opline";
65 return "method opline";
66 case FILE_PARAM:
67 return "file or file opline";
68 case STR_PARAM:
69 return "string";
70 default: /* this is bad */
71 return "unknown";
72 }
73}
74
76{
77 if (param) {
78 switch (param->type) {
79 case FILE_PARAM:
80 efree(param->file.name);
81 break;
82 case METHOD_PARAM:
83 efree(param->method.class);
84 efree(param->method.name);
85 break;
86 case STR_PARAM:
87 efree(param->str);
88 break;
89 default:
90 break;
91 }
92 }
93
94} /* }}} */
95
96PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer) /* {{{ */
97{
98 switch (param->type) {
99 case STR_PARAM:
100 ZEND_IGNORE_VALUE(asprintf(pointer, "%s", param->str));
101 break;
102
103 case ADDR_PARAM:
105 break;
106
107 case NUMERIC_PARAM:
108 ZEND_IGNORE_VALUE(asprintf(pointer, ZEND_LONG_FMT, param->num));
109 break;
110
111 case METHOD_PARAM:
112 ZEND_IGNORE_VALUE(asprintf(pointer, "%s::%s", param->method.class, param->method.name));
113 break;
114
115 case FILE_PARAM:
116 if (param->num) {
117 ZEND_IGNORE_VALUE(asprintf(pointer, "%s:"ZEND_ULONG_FMT"#"ZEND_ULONG_FMT, param->file.name, param->file.line, param->num));
118 } else {
119 ZEND_IGNORE_VALUE(asprintf(pointer, "%s:"ZEND_ULONG_FMT, param->file.name, param->file.line));
120 }
121 break;
122
124 ZEND_IGNORE_VALUE(asprintf(pointer, "%s#"ZEND_ULONG_FMT, param->str, param->num));
125 break;
126
128 ZEND_IGNORE_VALUE(asprintf(pointer, "%s::%s#"ZEND_ULONG_FMT, param->method.class, param->method.name, param->num));
129 break;
130
131 default:
132 *pointer = strdup("unknown");
133 }
134
135 return *pointer;
136} /* }}} */
137
139{
140 switch ((dest->type = src->type)) {
141 case STACK_PARAM:
142 /* nope */
143 break;
144
145 case STR_PARAM:
146 dest->str = estrndup(src->str, src->len);
147 dest->len = src->len;
148 break;
149
150 case OP_PARAM:
151 dest->str = estrndup(src->str, src->len);
152 dest->len = src->len;
153 break;
154
155 case ADDR_PARAM:
156 dest->addr = src->addr;
157 break;
158
159 case NUMERIC_PARAM:
160 dest->num = src->num;
161 break;
162
163 case METHOD_PARAM:
164 dest->method.class = estrdup(src->method.class);
165 dest->method.name = estrdup(src->method.name);
166 break;
167
169 case FILE_PARAM:
170 dest->file.name = estrdup(src->file.name);
171 dest->file.line = src->file.line;
172 if (src->num)
173 dest->num = src->num;
174 break;
175
177 dest->str = estrndup(src->str, src->len);
178 dest->num = src->num;
179 dest->len = src->len;
180 break;
181
183 dest->method.class = estrdup(src->method.class);
184 dest->method.name = estrdup(src->method.name);
185 dest->num = src->num;
186 break;
187
188 case EMPTY_PARAM: { /* do nothing */ } break;
189
190 default: {
191 /* not yet */
192 }
193 }
194} /* }}} */
195
197{
198 zend_ulong hash = param->type;
199
200 switch (param->type) {
201 case STACK_PARAM:
202 /* nope */
203 break;
204
205 case STR_PARAM:
206 hash += zend_hash_func(param->str, param->len);
207 break;
208
209 case METHOD_PARAM:
210 hash += zend_hash_func(param->method.class, strlen(param->method.class));
211 hash += zend_hash_func(param->method.name, strlen(param->method.name));
212 break;
213
214 case FILE_PARAM:
215 hash += zend_hash_func(param->file.name, strlen(param->file.name));
216 hash += param->file.line;
217 if (param->num)
218 hash += param->num;
219 break;
220
221 case ADDR_PARAM:
222 hash += param->addr;
223 break;
224
225 case NUMERIC_PARAM:
226 hash += param->num;
227 break;
228
230 hash += zend_hash_func(param->str, param->len);
231 hash += param->num;
232 break;
233
235 hash += zend_hash_func(param->method.class, strlen(param->method.class));
236 hash += zend_hash_func(param->method.name, strlen(param->method.name));
237 if (param->num)
238 hash+= param->num;
239 break;
240
241 case EMPTY_PARAM: { /* do nothing */ } break;
242
243 default: {
244 /* not yet */
245 }
246 }
247
248 return hash;
249} /* }}} */
250
252{
253 if (l && r) {
254 if (l->type == r->type) {
255 switch (l->type) {
256 case STACK_PARAM:
257 /* nope, or yep */
258 return 1;
259 break;
260
262 if (l->num != r->num) {
263 break;
264 }
266
267 case STR_PARAM:
268 return (l->len == r->len) &&
269 (memcmp(l->str, r->str, l->len) == SUCCESS);
270
271 case NUMERIC_PARAM:
272 return (l->num == r->num);
273
274 case ADDR_PARAM:
275 return (l->addr == r->addr);
276
277 case FILE_PARAM: {
278 if (l->file.line == r->file.line) {
279 size_t lengths[2] = {
280 strlen(l->file.name), strlen(r->file.name)};
281
282 if (lengths[0] == lengths[1]) {
283 if ((!l->num && !r->num) || (l->num == r->num)) {
284 return (memcmp(
285 l->file.name, r->file.name, lengths[0]) == SUCCESS);
286 }
287 }
288 }
289 } break;
290
292 if (l->num != r->num) {
293 break;
294 }
296
297 case METHOD_PARAM: {
298 size_t lengths[2] = {
300 if (lengths[0] == lengths[1]) {
301 if (memcmp(l->method.class, r->method.class, lengths[0]) == SUCCESS) {
302 lengths[0] = strlen(l->method.name);
303 lengths[1] = strlen(r->method.name);
304
305 if (lengths[0] == lengths[1]) {
306 return (memcmp(
307 l->method.name, r->method.name, lengths[0]) == SUCCESS);
308 }
309 }
310 }
311 } break;
312
313 case EMPTY_PARAM:
314 return 1;
315
316 default: {
317 /* not yet */
318 }
319 }
320 }
321 }
322 return 0;
323} /* }}} */
324
325/* {{{ */
326PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) {
327 if (param && param->type) {
328 switch (param->type) {
329 case STR_PARAM:
330 fprintf(stderr, "%s STR_PARAM(%s=%zu)\n", msg, param->str, param->len);
331 break;
332
333 case ADDR_PARAM:
334 fprintf(stderr, "%s ADDR_PARAM(" ZEND_ULONG_FMT ")\n", msg, param->addr);
335 break;
336
338 fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#"ZEND_ULONG_FMT")\n", msg, param->file.name, param->file.line);
339 break;
340
341 case FILE_PARAM:
342 fprintf(stderr, "%s FILE_PARAM(%s:"ZEND_ULONG_FMT")\n", msg, param->file.name, param->file.line);
343 break;
344
345 case METHOD_PARAM:
346 fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name);
347 break;
348
350 fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name);
351 break;
352
354 fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::"ZEND_LONG_FMT")\n", msg, param->str, param->num);
355 break;
356
357 case NUMERIC_PARAM:
358 fprintf(stderr, "%s NUMERIC_PARAM("ZEND_LONG_FMT")\n", msg, param->num);
359 break;
360
361 case COND_PARAM:
362 fprintf(stderr, "%s COND_PARAM(%s=%zu)\n", msg, param->str, param->len);
363 break;
364
365 case OP_PARAM:
366 fprintf(stderr, "%s OP_PARAM(%s=%zu)\n", msg, param->str, param->len);
367 break;
368
369 default: {
370 /* not yet */
371 }
372 }
373 }
374} /* }}} */
375
376/* {{{ */
378 ZEND_ASSERT(stack != NULL);
379
380 if (stack->next) {
381 phpdbg_param_t *remove = stack->next;
382
383 while (remove) {
385
386 if (remove->next)
387 next = remove->next;
388
389 switch (remove->type) {
391 case METHOD_PARAM:
392 if (remove->method.class) {
393 efree(remove->method.class);
394 }
395 if (remove->method.name) {
396 efree(remove->method.name);
397 }
398 break;
399
401 case STR_PARAM:
402 case OP_PARAM:
403 case EVAL_PARAM:
404 case SHELL_PARAM:
405 case COND_PARAM:
406 case RUN_PARAM:
407 if (remove->str) {
408 efree(remove->str);
409 }
410 break;
411
413 case FILE_PARAM:
414 if (remove->file.name) {
415 efree(remove->file.name);
416 }
417 break;
418
419 default: {
420 /* nothing */
421 }
422 }
423
424 free(remove);
425 remove = NULL;
426
427 if (next)
428 remove = next;
429 else break;
430 }
431
432 stack->next = NULL;
433 }
434} /* }}} */
435
436/* {{{ */
438 phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t));
439
440 if (!next) {
441 return;
442 }
443
444 *(next) = *(param);
445
446 next->next = NULL;
447
448 if (stack->top == NULL) {
449 stack->top = next;
450 next->top = NULL;
451 stack->next = next;
452 } else {
453 stack->top->next = next;
454 next->top = stack->top;
455 stack->top = next;
456 }
457
458 stack->len++;
459} /* }}} */
460
461/* {{{ */
463 phpdbg_param_t *stack = calloc(1, sizeof(phpdbg_param_t));
464
465 stack->type = STACK_PARAM;
466 stack->next = param->next;
467 param->next = stack;
468 stack->top = param->top;
469} /* }}} */
470
472 if (command) {
473 char buffer[128] = {0,};
474 const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL;
475 const char *arg = command->args;
476 zend_ulong least = 0L,
477 received = 0L,
478 current = 0L;
479 bool optional = 0;
480
481 /* check for arg spec */
482 if (!(arg) || !(*arg)) {
483 if (!top || top->type == STACK_PARAM) {
484 return SUCCESS;
485 }
486
487 phpdbg_error("The command \"%s\" expected no arguments",
488 phpdbg_command_name(command, buffer));
489 return FAILURE;
490 }
491
492 least = 0L;
493
494 /* count least amount of arguments */
495 while (arg && *arg) {
496 if (arg[0] == '|') {
497 break;
498 }
499 least++;
500 arg++;
501 }
502
503 arg = command->args;
504
505#define verify_arg(e, a, t) if (!(a)) { \
506 if (!optional) { \
507 phpdbg_error("The command \"%s\" expected %s and got nothing at parameter "ZEND_ULONG_FMT, \
508 phpdbg_command_name(command, buffer), \
509 (e), \
510 current); \
511 return FAILURE;\
512 } \
513} else if ((a)->type != (t)) { \
514 phpdbg_error("The command \"%s\" expected %s and got %s at parameter "ZEND_ULONG_FMT, \
515 phpdbg_command_name(command, buffer), \
516 (e),\
517 phpdbg_get_param_type((a)), \
518 current); \
519 return FAILURE; \
520}
521
522 while (arg && *arg) {
523 if (top && top->type == STACK_PARAM) {
524 break;
525 }
526
527 current++;
528
529 switch (*arg) {
530 case '|': {
531 current--;
532 optional = 1;
533 arg++;
534 } continue;
535
536 case 'i': verify_arg("raw input", top, STR_PARAM); break;
537 case 's': verify_arg("string", top, STR_PARAM); break;
538 case 'n': verify_arg("number", top, NUMERIC_PARAM); break;
539 case 'm': verify_arg("method", top, METHOD_PARAM); break;
540 case 'a': verify_arg("address", top, ADDR_PARAM); break;
541 case 'f': verify_arg("file:line", top, FILE_PARAM); break;
542 case 'c': verify_arg("condition", top, COND_PARAM); break;
543 case 'o': verify_arg("opcode", top, OP_PARAM); break;
544 case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break;
545
546 case '*': { /* do nothing */ } break;
547 }
548
549 if (top) {
550 top = top->next;
551 } else {
552 break;
553 }
554
555 received++;
556 arg++;
557 }
558
559#undef verify_arg
560
561 if ((received < least)) {
562 phpdbg_error("The command \"%s\" expected at least "ZEND_ULONG_FMT" arguments (%s) and received "ZEND_ULONG_FMT,
563 phpdbg_command_name(command, buffer),
564 least,
565 command->args,
566 received);
567 return FAILURE;
568 }
569 }
570
571 return SUCCESS;
572}
573
574/* {{{ */
576 const phpdbg_command_t *command = commands;
578 const phpdbg_command_t *matched[3] = {NULL, NULL, NULL};
579 zend_ulong matches = 0L;
580
581 while (command && command->name && command->handler) {
582 if (name->len == 1 || command->name_len >= name->len) {
583 /* match single letter alias */
584 if (command->alias && (name->len == 1)) {
585 if (command->alias == (*name->str)) {
586 matched[matches] = command;
587 matches++;
588 }
589 } else {
590 /* match full, case insensitive, command name */
591 if (strncasecmp(command->name, name->str, name->len) == SUCCESS) {
592 if (matches < 3) {
593 /* only allow abbreviating commands that can be aliased */
594 if ((name->len != command->name_len && command->alias) || name->len == command->name_len) {
595 matched[matches] = command;
596 matches++;
597 }
598
599 /* exact match */
600 if (name->len == command->name_len) {
601 break;
602 }
603 } else {
604 break;
605 }
606 }
607 }
608 }
609
610 command++;
611 }
612
613 switch (matches) {
614 case 0:
615 if (parent) {
616 phpdbg_error("The command \"%s %s\" could not be found", parent->name, name->str);
617 } else {
618 phpdbg_error("The command \"%s\" could not be found", name->str);
619 }
620 return parent;
621
622 case 1:
623 (*top) = (*top)->next;
624
625 command = matched[0];
626 break;
627
628 default: {
629 char *list = NULL;
630 uint32_t it = 0;
631 size_t pos = 0;
632
633 while (it < matches) {
634 if (!list) {
635 list = emalloc(matched[it]->name_len + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0));
636 } else {
637 list = erealloc(list, (pos + matched[it]->name_len) + 1 + (it + 1 < matches ? sizeof(", ") - 1 : 0));
638 }
639 memcpy(&list[pos], matched[it]->name, matched[it]->name_len);
640 pos += matched[it]->name_len;
641 if ((it + 1) < matches) {
642 memcpy(&list[pos], ", ", sizeof(", ") - 1);
643 pos += (sizeof(", ") - 1);
644 }
645
646 list[pos] = 0;
647 it++;
648 }
649
650 /* ", " separated matches */
651 phpdbg_error("The command \"%s\" is ambiguous, matching "ZEND_ULONG_FMT" commands (%s)", name->str, matches, list);
652 efree(list);
653
654 return NULL;
655 }
656 }
657
658 if (command->subs && (*top) && ((*top)->type == STR_PARAM)) {
659 return phpdbg_stack_resolve(command->subs, command, top);
660 } else {
661 return command;
662 }
663
664 return NULL;
665} /* }}} */
666
667static int phpdbg_internal_stack_execute(phpdbg_param_t *stack, bool allow_async_unsafe) {
670
671 switch (top->type) {
672 case EVAL_PARAM:
675 return PHPDBG_COMMAND_HANDLER(ev)(top);
676
677 case RUN_PARAM:
678 if (!allow_async_unsafe) {
679 phpdbg_error("run command is disallowed during hard interrupt");
680 }
683 return PHPDBG_COMMAND_HANDLER(run)(top);
684
685 case SHELL_PARAM:
686 if (!allow_async_unsafe) {
687 phpdbg_error("sh command is disallowed during hard interrupt");
688 return FAILURE;
689 }
692 return PHPDBG_COMMAND_HANDLER(sh)(top);
693
694 case STR_PARAM: {
696
697 if (handler) {
698 if (!allow_async_unsafe && !(handler->flags & PHPDBG_ASYNC_SAFE)) {
699 phpdbg_error("%s command is disallowed during hard interrupt", handler->name);
700 return FAILURE;
701 }
702
706 return handler->handler(top);
707 }
708 }
709 } return FAILURE;
710
711 default:
712 phpdbg_error("The first parameter makes no sense !");
713 return FAILURE;
714 }
715
716 return SUCCESS;
717} /* }}} */
718
719/* {{{ */
720PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, bool allow_async_unsafe) {
721 phpdbg_param_t *top = stack;
722
723 if (stack->type != STACK_PARAM) {
724 phpdbg_error("The passed argument was not a stack !");
725 return FAILURE;
726 }
727
728 if (!stack->len) {
729 phpdbg_error("The stack contains nothing !");
730 return FAILURE;
731 }
732
733 do {
734 if (top->type == STACK_PARAM) {
735 int result;
736 if ((result = phpdbg_internal_stack_execute(top, allow_async_unsafe)) != SUCCESS) {
737 return result;
738 }
739 }
740 } while ((top = top->next));
741
742 return SUCCESS;
743} /* }}} */
744
745PHPDBG_API char *phpdbg_read_input(const char *buffered) /* {{{ */
746{
747 char *buffer = NULL;
748
750 if (buffered == NULL) {
751#ifdef HAVE_PHPDBG_READLINE
752# ifdef HAVE_UNISTD_H
753 /* EOF makes readline write prompt again in local console mode and
754 ignored if compiled without readline integration. */
755 if (!isatty(PHPDBG_G(io)[PHPDBG_STDIN].fd)) {
756 char buf[PHPDBG_MAX_CMD];
759 buffer = estrdup(buf);
760 } else
761# endif
762 {
763 char *cmd = readline(phpdbg_get_prompt());
765
766 if (!cmd) {
768 zend_bailout();
769 }
770
771 add_history(cmd);
772 buffer = estrdup(cmd);
773 free(cmd);
774 }
775#else
776 char buf[PHPDBG_MAX_CMD];
779 buffer = estrdup(buf);
780#endif
781 } else {
782 buffer = estrdup(buffered);
783 }
784 }
785
786 if (buffer && isspace(*buffer)) {
787 char *trimmed = buffer;
788 while (isspace(*trimmed))
789 trimmed++;
790
791 trimmed = estrdup(trimmed);
792 efree(buffer);
793 buffer = trimmed;
794 }
795
796 if (buffer && strlen(buffer)) {
797 if (PHPDBG_G(buffer)) {
798 free(PHPDBG_G(buffer));
799 }
800 PHPDBG_G(buffer) = strdup(buffer);
801 } else if (PHPDBG_G(buffer)) {
802 if (buffer) {
803 efree(buffer);
804 }
806 }
807
808 return buffer;
809} /* }}} */
810
811PHPDBG_API void phpdbg_destroy_input(char **input) /*{{{ */
812{
813 efree(*input);
814} /* }}} */
815
816PHPDBG_API int phpdbg_ask_user_permission(const char *question) {
817 char buf[PHPDBG_MAX_CMD];
818 phpdbg_out("%s", question);
819 phpdbg_out(" (type y or n): ");
820
821 while (1) {
823 if ((buf[1] == '\n' || (buf[1] == '\r' && buf[2] == '\n')) && (buf[0] == 'y' || buf[0] == 'n')) {
824 if (buf[0] == 'y') {
825 return SUCCESS;
826 }
827 return FAILURE;
828 }
829 phpdbg_out("Please enter either y (yes) or n (no): ");
830 }
831
832 return SUCCESS;
833}
fprintf($stream, string $format, mixed ... $values)
Definition test.php:8
memcpy(ptr1, ptr2, size)
zval * arg
Definition ffi.c:3975
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
hash(string $algo, string $data, bool $binary=false, array $options=[])
Definition hash.stub.php:12
#define SUCCESS
Definition hash_sha3.c:261
#define next(ls)
Definition minilua.c:2661
unsigned const char * pos
Definition php_ffi.h:52
struct @234323133100145062121301312242002332057146367313 io[PHPDBG_IO_FDS]
#define PHPDBG_STDIN
Definition phpdbg.h:189
char * msg
Definition phpdbg.h:289
#define PHPDBG_G(v)
Definition phpdbg.h:102
#define PHPDBG_API
Definition phpdbg.h:27
int fd
Definition phpdbg.h:282
bool last_was_newline
Definition phpdbg.h:297
#define PHPDBG_IS_RUNNING
Definition phpdbg.h:150
#define PHPDBG_IS_QUITTING
Definition phpdbg.h:147
#define PHPDBG_IS_STOPPING
Definition phpdbg.h:171
PHPDBG_API const char * phpdbg_get_param_type(const phpdbg_param_t *param)
Definition phpdbg_cmd.c:49
PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, bool allow_async_unsafe)
Definition phpdbg_cmd.c:720
#define verify_arg(e, a, t)
PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t *src, phpdbg_param_t *dest)
Definition phpdbg_cmd.c:138
PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
Definition phpdbg_cmd.c:326
PHPDBG_API bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_param_t *r)
Definition phpdbg_cmd.c:251
PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param)
Definition phpdbg_cmd.c:196
PHPDBG_API char * phpdbg_read_input(const char *buffered)
Definition phpdbg_cmd.c:745
PHPDBG_API void phpdbg_destroy_input(char **input)
Definition phpdbg_cmd.c:811
PHPDBG_API void phpdbg_stack_separate(phpdbg_param_t *param)
Definition phpdbg_cmd.c:462
PHPDBG_API char * phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer)
Definition phpdbg_cmd.c:96
PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param)
Definition phpdbg_cmd.c:437
PHPDBG_API const phpdbg_command_t * phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top)
Definition phpdbg_cmd.c:575
PHPDBG_API int phpdbg_ask_user_permission(const char *question)
Definition phpdbg_cmd.c:816
PHPDBG_API void phpdbg_clear_param(phpdbg_param_t *param)
Definition phpdbg_cmd.c:75
PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack)
Definition phpdbg_cmd.c:471
PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack)
Definition phpdbg_cmd.c:377
struct _phpdbg_param phpdbg_param_t
Definition phpdbg_cmd.h:51
@ NUMERIC_FILE_PARAM
Definition phpdbg_cmd.h:36
@ EVAL_PARAM
Definition phpdbg_cmd.h:43
@ EMPTY_PARAM
Definition phpdbg_cmd.h:33
@ ADDR_PARAM
Definition phpdbg_cmd.h:34
@ OP_PARAM
Definition phpdbg_cmd.h:46
@ NUMERIC_METHOD_PARAM
Definition phpdbg_cmd.h:41
@ SHELL_PARAM
Definition phpdbg_cmd.h:44
@ STACK_PARAM
Definition phpdbg_cmd.h:42
@ STR_PARAM
Definition phpdbg_cmd.h:38
@ COND_PARAM
Definition phpdbg_cmd.h:45
@ METHOD_PARAM
Definition phpdbg_cmd.h:37
@ FILE_PARAM
Definition phpdbg_cmd.h:35
@ RUN_PARAM
Definition phpdbg_cmd.h:48
@ NUMERIC_PARAM
Definition phpdbg_cmd.h:39
@ NUMERIC_FUNCTION_PARAM
Definition phpdbg_cmd.h:40
#define PHPDBG_MAX_CMD
Definition phpdbg_cmd.h:105
struct _phpdbg_command_t phpdbg_command_t
Definition phpdbg_cmd.h:88
#define PHPDBG_ASYNC_SAFE
Definition phpdbg_cmd.h:84
#define PHPDBG_COMMAND_HANDLER(name)
Definition phpdbg_cmd.h:156
PHPDBG_API int phpdbg_consume_stdin_line(char *buf)
Definition phpdbg_io.c:26
PHPDBG_API void phpdbg_free_err_buf(void)
Definition phpdbg_out.c:159
PHPDBG_API void phpdbg_activate_err_buf(bool active)
Definition phpdbg_out.c:169
#define phpdbg_error(strfmt,...)
Definition phpdbg_out.h:43
#define phpdbg_out(fmt,...)
Definition phpdbg_out.h:49
#define phpdbg_write(strfmt,...)
Definition phpdbg_out.h:46
const phpdbg_command_t phpdbg_prompt_commands[]
original_stack top
PHPDBG_API const char * phpdbg_get_prompt(void)
readline(?string $prompt=null)
zval * current
Definition session.c:1024
#define asprintf
Definition snprintf.h:111
const phpdbg_command_t * subs
Definition phpdbg_cmd.h:96
phpdbg_command_handler_t handler
Definition phpdbg_cmd.h:95
const char * name
Definition phpdbg_cmd.h:90
const phpdbg_command_t * parent
Definition phpdbg_cmd.h:98
zend_ulong line
Definition phpdbg_cmd.h:58
struct _phpdbg_param::@330020305320302230147242007301032363271275050165 file
phpdbg_param_t * top
Definition phpdbg_cmd.h:67
phpdbg_param_type type
Definition phpdbg_cmd.h:53
zend_ulong addr
Definition phpdbg_cmd.h:55
zend_long num
Definition phpdbg_cmd.h:54
phpdbg_param_t * next
Definition phpdbg_cmd.h:66
struct _phpdbg_param::@004226021353141374347100337026301377067143131166 method
Definition file.h:177
#define zend_bailout()
Definition zend.h:268
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)
Definition zend_API.h:270
#define estrndup(s, length)
Definition zend_alloc.h:165
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
#define erealloc(ptr, size)
Definition zend_alloc.h:159
#define emalloc(size)
Definition zend_alloc.h:151
strlen(string $string)
#define strncasecmp(s1, s2, n)
#define ZEND_ULONG_FMT
Definition zend_long.h:88
uint32_t zend_ulong
Definition zend_long.h:43
#define ZEND_LONG_FMT
Definition zend_long.h:87
#define ZEND_IGNORE_VALUE(x)
#define ZEND_FALLTHROUGH
#define ZEND_ASSERT(c)
ZEND_DLIMPORT int isatty(int fd)
ZEND_API zend_ulong ZEND_FASTCALL zend_hash_func(const char *str, size_t len)
Definition zend_string.c:60
@ FAILURE
Definition zend_types.h:61
zend_string * name
fbc internal_function handler(call, ret)
bool result