Пример #1
0
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());
    }
}
Пример #2
0
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);
}