diff --git a/builtin.cpp b/builtin.cpp index 3c444c506..f3f7af1f9 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -2714,7 +2714,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) Implementation of the builtin count command, used to count the number of arguments sent to it. */ -static int builtin_count( wchar_t ** argv ) +static int builtin_count( parser_t &parser, wchar_t ** argv ) { int argc; argc = builtin_count_args( argv ); @@ -3851,19 +3851,19 @@ static int internal_help( wchar_t *cmd ) } -int builtin_run( wchar_t **argv, io_data_t *io ) +int builtin_run( parser_t &parser, wchar_t **argv, io_data_t *io ) { - int (*cmd)(wchar_t **argv)=0; + int (*cmd)(parser_t &parser, wchar_t **argv)=0; real_io = io; CHECK( argv, STATUS_BUILTIN_ERROR ); CHECK( argv[0], STATUS_BUILTIN_ERROR ); - cmd = (int (*)(wchar_t **))hash_get( &builtin, argv[0] ); + cmd = (int (*)(parser_t &parser, wchar_t **))hash_get( &builtin, argv[0] ); if( argv[1] != 0 && !internal_help(argv[0]) ) { - if( argv[2] == 0 && (parser_is_help( argv[1], 0 ) ) ) + if( argv[2] == 0 && (parser.is_help( argv[1], 0 ) ) ) { builtin_print_help( parser, argv[0], sb_out ); return STATUS_BUILTIN_OK; @@ -3874,7 +3874,7 @@ int builtin_run( wchar_t **argv, io_data_t *io ) { int status; - status = cmd(argv); + status = cmd(parser, argv); return status; } diff --git a/builtin.h b/builtin.h index 788749b54..e14bdc72c 100644 --- a/builtin.h +++ b/builtin.h @@ -157,7 +157,7 @@ void builtin_pop_io(parser_t &parser); /** Return a one-line description of the specified builtin */ -const wchar_t *builtin_get_desc( parser_t &parser, const wchar_t *b ); +const wchar_t *builtin_get_desc( const wchar_t *b ); /** diff --git a/builtin_commandline.cpp b/builtin_commandline.cpp index 0ead09949..2615db733 100644 --- a/builtin_commandline.cpp +++ b/builtin_commandline.cpp @@ -232,7 +232,7 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) int search_mode = 0; wchar_t *begin, *end; - current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer(); + current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer(parser); if( current_buffer ) { current_cursor_pos = wcslen( current_buffer ); diff --git a/parser.cpp b/parser.cpp index 55875adb4..7d273b2ff 100644 --- a/parser.cpp +++ b/parser.cpp @@ -390,11 +390,6 @@ static std::vector forbidden_function; */ static int job_start_pos; -/** - List of all profiling data -*/ -static array_list_t profile_data; - /** Keeps track of how many recursive eval calls have been made. Eval doesn't call itself directly, recursion happens on blocks and on @@ -433,6 +428,29 @@ typedef struct wchar_t *cmd; } profile_element_t; +struct profile_item_t { + /** + Time spent executing the specified command, including parse time for nested blocks. + */ + int exec; + /** + Time spent parsing the specified command, including execution time for command substitutions. + */ + int parse; + /** + The block level of the specified command. nested blocks and command substitutions both increase the block level. + */ + int level; + /** + If the execution of this command was skipped. + */ + int skipped; + /** + The command string. + */ + wcstring cmd; +}; + /** Return the current number of block nestings */ @@ -666,14 +684,6 @@ void error( int ec, int p, const wchar_t *str, ... ) } -void parser_init() -{ - if( profile ) - { - al_init( &profile_data); - } -} - /** Print profiling information to the specified stream */ @@ -765,7 +775,7 @@ void parser_destroy() { if( fwprintf( f, _(L"Time\tSum\tCommand\n"), - al_get_count( &profile_data ) ) < 0 ) + profile_items.size() ) < 0 ) { wperror( L"fwprintf" ); } @@ -779,7 +789,6 @@ void parser_destroy() wperror( L"fclose" ); } } - al_destroy( &profile_data ); } if( lineinfo ) @@ -2291,24 +2300,24 @@ static void skipped_exec( job_t * j ) \param tok The tokenizer to read tokens from */ -static void eval_job( tokenizer *tok ) +static void eval_job( parser_t &parser, tokenizer *tok ) { job_t *j; int start_pos = job_start_pos = tok_get_pos( tok ); long long t1=0, t2=0, t3=0; - profile_element_t *p=0; + + + profile_item_t *profile_item = NULL; int skip = 0; int job_begin_pos, prev_tokenizer_pos; if( profile ) { - p=(profile_element_t*)malloc( sizeof(profile_element_t)); - if( !p ) - DIE_MEM(); - p->cmd=0; - al_push( &profile_data, p ); - p->skipped=1; + parser.profile_items.resize(parser.profile_items.size() + 1); + profile_item = &parser.profile_items.back(); + profile_item->cmd = L""; + profile_item->skipped = 1; t1 = get_time(); } @@ -2364,8 +2373,8 @@ static void eval_job( tokenizer *tok ) if( profile ) { t2 = get_time(); - p->cmd = wcsdup( j->command ); - p->skipped=current_block->skip; + profile_item->cmd = wcsdup( j->command ); + profile_item->skipped=current_block->skip; } skip |= current_block->skip; @@ -2394,9 +2403,9 @@ static void eval_job( tokenizer *tok ) if( profile ) { t3 = get_time(); - p->level=eval_level; - p->parse = t2-t1; - p->exec=t3-t2; + profile_item->level=eval_level; + profile_item->parse = t2-t1; + profile_item->exec=t3-t2; } if( current_block->type == WHILE ) @@ -2551,7 +2560,7 @@ int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) !sanity_check() && !exit_status() ) { - eval_job( current_tokenizer ); + eval_job( parser, current_tokenizer ); event_fire( NULL ); } diff --git a/parser.h b/parser.h index 615f6708a..8c465d0af 100644 --- a/parser.h +++ b/parser.h @@ -187,6 +187,8 @@ enum parser_type_t { PARSER_TYPE_COMPLETIONS_ONLY }; +struct profile_item_t; + class parser_t { private: std::vector blocks; @@ -196,6 +198,7 @@ class parser_t { parser_t& operator=(const parser_t&); public: + std::vector profile_items; /** Create a parser of the given type */ parser_t(enum parser_type_t type);