From 91de143003c17571f028a06db23086758b16697f Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 1 Aug 2007 07:23:32 +1000 Subject: [PATCH] Replace the count function with a builtin for performance reasons. The count function used at least two forks, which was noticable on systems such as OS X with slow forks darcs-hash:20070731212332-ac50b-8f5b2e70008ddb131dc8bae3f361d8d65a294948.gz --- builtin.c | 38 ++++++++++++++++---------------------- doc_src/count.txt | 2 +- parser.c | 17 ++++++++--------- proc.h | 12 ++++++++++++ share/functions/count.fish | 11 ----------- 5 files changed, 37 insertions(+), 43 deletions(-) delete mode 100644 share/functions/count.fish diff --git a/builtin.c b/builtin.c index 968834836..df6eba19e 100644 --- a/builtin.c +++ b/builtin.c @@ -626,7 +626,10 @@ static int builtin_block( wchar_t **argv ) } /** - The builtin builtin, used for given builtins precedence over functions. Mostly handled by the parser. All this code does is some additional operational modes, such as printing a list of all builtins. + The builtin builtin, used for given builtins precedence over + functions. Mostly handled by the parser. All this code does is some + additional operational modes, such as printing a list of all + builtins. */ static int builtin_builtin( wchar_t **argv ) { @@ -706,9 +709,6 @@ static int builtin_builtin( wchar_t **argv ) { wchar_t *el = (wchar_t *)al_get( &names, i ); - if( wcscmp( el, L"count" ) == 0 ) - continue; - sb_append2( sb_out, el, L"\n", @@ -2227,6 +2227,13 @@ static int builtin_cd( wchar_t **argv ) } +static int builtin_count( wchar_t ** argv ) +{ + int argc; + argc = builtin_count_args( argv ); + sb_printf( sb_out, L"%d\n", argc-1 ); + return !argc; +} /** The . (dot) builtin, sometimes called source. Evaluates the contents of a file. @@ -3057,6 +3064,10 @@ const static builtin_data_t builtin_data[]= L"cd", &builtin_cd, N_( L"Change working directory" ) } , + { + L"count", &builtin_count, N_( L"Count the number of arguments" ) + } + , { L"function", &builtin_function, N_( L"Define a new function" ) } @@ -3187,16 +3198,6 @@ const static builtin_data_t builtin_data[]= L"exec", &builtin_generic, N_( L"Run command in current process" ) } , - - /* - This is not a builtin, but fish handles it's help display - internally. So some ugly special casing to make sure 'count -h' - displays the help for count, but 'count (echo -h)' does not. - */ - { - L"count", &builtin_generic, N_( L"Count the number of arguments" ) - } - , { 0, 0, 0 } @@ -3238,13 +3239,6 @@ int builtin_exists( wchar_t *cmd ) { CHECK( cmd, 0 ); - /* - Count is not a builtin, but it's help is handled internally by - fish, so it is in the hash_table_t. - */ - if( wcscmp( cmd, L"count" )==0) - return 0; - return !!hash_get(&builtin, cmd); } @@ -3274,7 +3268,7 @@ int builtin_run( wchar_t **argv, io_data_t *io ) CHECK( argv[0], STATUS_BUILTIN_ERROR ); cmd = (int (*)(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 ) ) ) diff --git a/doc_src/count.txt b/doc_src/count.txt index ca4b5d044..8b6b14c61 100644 --- a/doc_src/count.txt +++ b/doc_src/count.txt @@ -5,7 +5,7 @@ \subsection count-description Description -The count function prints the number of arguments that were +The count builtin prints the number of arguments that were passed to it. This is usually used to find out how many elements an environment variable array contains, but this is not the only potential usage for the count command. diff --git a/parser.c b/parser.c index 83e88533c..bec353837 100644 --- a/parser.c +++ b/parser.c @@ -1401,18 +1401,17 @@ static void parse_job_argument_list( process_t *p, if( !skip ) { - if( proc_is_count && - (al_get_count( args) == 1) && - ( parser_is_help( tok_last(tok), 0) ) ) + if( ( proc_is_count ) && + ( al_get_count( args) == 1) && + ( parser_is_help( tok_last(tok), 0) ) && + ( p->type == INTERNAL_BUILTIN ) ) { /* Display help for count */ - p->type = INTERNAL_BUILTIN; - p->actual_cmd = L"count"; + p->count_help_magic = 1; } - switch( expand_string( j, wcsdup(tok_last( tok )), args, 0 ) ) { case EXPAND_ERROR: @@ -1421,9 +1420,9 @@ static void parse_job_argument_list( process_t *p, if( error_code == 0 ) { error( SYNTAX_ERROR, - tok_get_pos( tok ), - _(L"Could not expand string '%ls'"), - tok_last(tok) ); + tok_get_pos( tok ), + _(L"Could not expand string '%ls'"), + tok_last(tok) ); } break; diff --git a/proc.h b/proc.h index 20ad038f0..4d266ca6d 100644 --- a/proc.h +++ b/proc.h @@ -126,22 +126,34 @@ typedef struct process INTERNAL_EXEC, or INTERNAL_BUFFER */ int type; + /** argv parameter for for execv, builtin_run, etc. */ wchar_t **argv; + /** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC */ wchar_t *actual_cmd; + /** process ID */ pid_t pid; + /** File descriptor that pipe output should bind to */ int pipe_write_fd; + /** File descriptor that the _next_ process pipe input should bind to */ int pipe_read_fd; + /** true if process has completed */ volatile int completed; + /** true if process has stopped */ volatile int stopped; + /** reported status value */ volatile int status; + + /** Special flag to tell the evaluation function for count to print the help information */ + int count_help_magic; + /** next process in pipeline */ struct process *next; #ifdef HAVE__PROC_SELF_STAT diff --git a/share/functions/count.fish b/share/functions/count.fish deleted file mode 100644 index 1ddb30b54..000000000 --- a/share/functions/count.fish +++ /dev/null @@ -1,11 +0,0 @@ - -function count --description "Count the number of elements of an array" - set -l lines '' - set result 1 - for i in $argv - set lines $lines\n - set result 0 - end - echo -n $lines|wc -l - return $result -end