static void show_all_handlers(void) { puts("event handlers:"); for (event_list_t::const_iterator iter = events.begin(); iter != events.end(); ++iter) { const event_t *foo = *iter; wcstring tmp = event_get_desc(foo); printf(" handler now %ls\n", tmp.c_str()); } }
void parser_t::stack_trace_internal(size_t block_idx, wcstring *buff) const { // Check if we should end the recursion. if (block_idx >= this->block_count()) return; const block_t *b = this->block_at_index(block_idx); if (b->type() == EVENT) { // This is an event handler. const event_block_t *eb = static_cast<const event_block_t *>(b); wcstring description = event_get_desc(eb->event); append_format(*buff, _(L"in event handler: %ls\n"), description.c_str()); buff->append(L"\n"); // Stop recursing at event handler. No reason to believe that any other code is relevant. // // It might make sense in the future to continue printing the stack trace of the code that // invoked the event, if this is a programmatic event, but we can't currently detect that. return; } if (b->type() == FUNCTION_CALL || b->type() == FUNCTION_CALL_NO_SHADOW || b->type() == SOURCE || b->type() == SUBST) { // These types of blocks should be printed. int i; switch (b->type()) { case SOURCE: { const source_block_t *sb = static_cast<const source_block_t *>(b); const wchar_t *source_dest = sb->source_file; append_format(*buff, _(L"from sourcing file %ls\n"), user_presentable_path(source_dest).c_str()); break; } case FUNCTION_CALL: case FUNCTION_CALL_NO_SHADOW: { const function_block_t *fb = static_cast<const function_block_t *>(b); append_format(*buff, _(L"in function '%ls'\n"), fb->name.c_str()); break; } case SUBST: { append_format(*buff, _(L"in command substitution\n")); break; } default: { break; // can't get here } } const wchar_t *file = b->src_filename; if (file) { append_format(*buff, _(L"\tcalled on line %d of file %ls\n"), b->src_lineno, user_presentable_path(file).c_str()); } else if (is_within_fish_initialization) { append_format(*buff, _(L"\tcalled during startup\n")); } else { append_format(*buff, _(L"\tcalled on standard input\n")); } if (b->type() == FUNCTION_CALL) { const function_block_t *fb = static_cast<const function_block_t *>(b); const process_t *const process = fb->process; if (process->argv(1)) { wcstring tmp; for (i = 1; process->argv(i); i++) { if (i > 1) tmp.push_back(L' '); tmp.append(process->argv(i)); } append_format(*buff, _(L"\twith parameter list '%ls'\n"), tmp.c_str()); } } append_format(*buff, L"\n"); } // Recursively print the next block. parser_t::stack_trace_internal(block_idx + 1, buff); }