#include "phpdbg_utils.h"
#include "phpdbg_break.h"
#include "phpdbg_list.h"
+#include "phpdbg_info.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
return SUCCESS;
} /* }}} */
+PHPDBG_HELP(info) /* {{{ */
+{
+ phpdbg_help_header();
+ phpdbg_writeln("info commands provides quick access to various types of information about the PHP environment");
+ phpdbg_writeln("Specific info commands are show below:");
+ phpdbg_notice("Commands");
+ {
+ const phpdbg_command_t *info_command = phpdbg_info_commands;
+
+ phpdbg_writeln("\tAlias\tCommand\t\tPurpose");
+ while (info_command && info_command->name) {
+ if (info_command->alias) {
+ phpdbg_writeln("\t[%c]\t%s\t\t%s", info_command->alias, info_command->name, info_command->tip);
+ } else phpdbg_writeln("\t[-]\t%s\t\t%s", info_command->name, info_command->tip);
+ ++info_command;
+ }
+ }
+
+ phpdbg_help_footer();
+ return SUCCESS;
+} /* }}} */
+
PHPDBG_HELP(quiet) /* {{{ */
{
phpdbg_help_header();
PHPDBG_HELP(break);
PHPDBG_HELP(clean);
PHPDBG_HELP(clear);
+PHPDBG_HELP(info);
PHPDBG_HELP(back);
PHPDBG_HELP(quiet);
PHPDBG_HELP(list);
PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'),
PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'),
PHPDBG_HELP_D(clear, "clearing breakpoints allows you to run code without interruption", 'c'),
+ PHPDBG_HELP_D(info, "quick access to useful information on the console", 'i'),
PHPDBG_HELP_D(back, "show debug backtrace information during execution", 't'),
PHPDBG_HELP_D(quiet, "be quiet during execution", 's'),
PHPDBG_HELP_D(list, "listing code gives you quick access to code while executing", 'l'),
return SUCCESS;
} /* }}} */
+
+static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) { /* {{{ */
+ phpdbg_write(
+ "%s %s %s (%d)",
+ ((*ce)->type == ZEND_USER_CLASS) ?
+ "User" : "Internal",
+ ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
+ "Interface" :
+ ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
+ "Abstract Class" :
+ "Class",
+ (*ce)->name, zend_hash_num_elements(&(*ce)->function_table));
+} /* }}} */
+
+PHPDBG_INFO(classes) /* {{{ */
+{
+ HashPosition position;
+ zend_class_entry **ce;
+ HashTable classes;
+
+ zend_hash_init(&classes, 8, NULL, NULL, 0);
+
+ for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position);
+ zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS;
+ zend_hash_move_forward_ex(EG(class_table), &position)) {
+
+ if ((*ce)->type == ZEND_USER_CLASS) {
+ zend_hash_next_index_insert(
+ &classes, ce, sizeof(ce), NULL);
+ }
+ }
+
+ phpdbg_notice("User Classes (%d)",
+ zend_hash_num_elements(&classes));
+
+ for (zend_hash_internal_pointer_reset_ex(&classes, &position);
+ zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS;
+ zend_hash_move_forward_ex(&classes, &position)) {
+
+ phpdbg_print_class_name(ce TSRMLS_CC);
+ phpdbg_writeln(EMPTY);
+
+ if ((*ce)->parent) {
+ zend_class_entry *pce = (*ce)->parent;
+ do {
+ phpdbg_write("|-------- ");
+ phpdbg_print_class_name(&pce TSRMLS_CC);
+ phpdbg_writeln(EMPTY);
+ } while(pce = pce->parent);
+ }
+
+ if ((*ce)->info.user.filename) {
+ phpdbg_writeln(
+ "|---- in %s on line %lu",
+ (*ce)->info.user.filename,
+ (*ce)->info.user.line_start);
+ } else phpdbg_writeln("|---- no source code");
+ }
+
+ zend_hash_destroy(&classes);
+
+ return SUCCESS;
+} /* }}} */
+
+
int PHPDBG_INFO_HANDLER(name)(phpdbg_param_t *param TSRMLS_DC)
PHPDBG_INFO(files);
+PHPDBG_INFO(classes);
static const phpdbg_command_t phpdbg_info_commands[] = {
- PHPDBG_INFO_EX_D(files, "lists included files", 'f'),
+ PHPDBG_INFO_EX_D(files, "lists included files", 'F'),
+ PHPDBG_INFO_EX_D(classes, "lists loaded classes", 'c'),
PHPDBG_END_COMAND
};