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
This commit is contained in:
axel 2007-08-01 07:23:32 +10:00
parent 748d726ddf
commit 91de143003
5 changed files with 37 additions and 43 deletions

View file

@ -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 ) ) )

View file

@ -5,7 +5,7 @@
\subsection count-description Description
The <tt>count</tt> function prints the number of arguments that were
The <tt>count</tt> 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.

View file

@ -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;

12
proc.h
View file

@ -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

View file

@ -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