Allow named arguments to function instead of only $argv. Philip Ganchev once suggested this, and it was suggested again by Egil Möller.

darcs-hash:20070416200611-ac50b-5eb42c94a65a4e72cae12cd9c04424bdc3b2b4f8.gz
This commit is contained in:
axel 2007-04-17 06:06:11 +10:00
parent a03a4d1ba3
commit 4d6751c274
6 changed files with 122 additions and 29 deletions

View file

@ -1081,6 +1081,7 @@ typedef struct function_data
wchar_t *name;
wchar_t *description;
array_list_t *events;
array_list_t *named_arguments;
}
function_data_t;
@ -1097,7 +1098,10 @@ static int builtin_function( wchar_t **argv )
wchar_t *desc=0;
array_list_t *events;
int i;
array_list_t *named_arguments=0;
wchar_t *name = 0;
woptind=0;
parser_push_block( FUNCTION_DEF );
@ -1130,6 +1134,10 @@ static int builtin_function( wchar_t **argv )
L"help", no_argument, 0, 'h'
}
,
{
L"argument-names", no_argument, 0, 'a'
}
,
{
0, 0, 0, 0
}
@ -1142,7 +1150,7 @@ static int builtin_function( wchar_t **argv )
int opt = wgetopt_long( argc,
argv,
L"d:s:j:p:v:h",
L"d:s:j:p:v:ha",
long_options,
&opt_index );
if( opt == -1 )
@ -1291,6 +1299,12 @@ static int builtin_function( wchar_t **argv )
break;
}
case 'a':
if( !named_arguments )
named_arguments = al_halloc( current_block );
break;
case 'h':
builtin_print_help( argv[0], sb_out );
return STATUS_BUILTIN_OK;
@ -1306,12 +1320,12 @@ static int builtin_function( wchar_t **argv )
if( !res )
{
if( argc-woptind != 1 )
if( argc == woptind )
{
sb_printf( sb_err,
_( L"%ls: Expected one argument, got %d\n" ),
argv[0],
argc-woptind );
_( L"%ls: Expected function name\n" ),
argv[0] );
res=1;
}
else if( wcsfuncname( argv[woptind] ) )
@ -1333,6 +1347,28 @@ static int builtin_function( wchar_t **argv )
res=1;
}
else
{
name = argv[woptind++];
if( named_arguments )
{
while( woptind < argc )
{
al_push( named_arguments, halloc_wcsdup( current_block, argv[woptind++] ) );
}
}
else if( woptind != argc )
{
sb_printf( sb_err,
_( L"%ls: Expected one argument, got %d\n" ),
argv[0],
argc );
res=1;
}
}
}
if( res )
@ -1373,9 +1409,10 @@ static int builtin_function( wchar_t **argv )
{
function_data_t * d = halloc( current_block, sizeof( function_data_t ));
d->name=halloc_wcsdup( current_block, argv[woptind]);
d->name=halloc_wcsdup( current_block, name);
d->description=desc?halloc_wcsdup( current_block, desc):0;
d->events = events;
d->named_arguments = named_arguments;
for( i=0; i<al_get_count( events ); i++ )
{
@ -2247,7 +2284,7 @@ static int builtin_source( wchar_t ** argv )
current_block->param1.source_dest = fn_intern;
parse_util_set_argv( argv+2);
parse_util_set_argv( argv+2, 0);
res = reader_read( fd );
@ -2645,7 +2682,8 @@ static void builtin_end_add_function_def( function_data_t *d )
function_add( d->name,
def,
d->description,
d->events );
d->events,
d->named_arguments );
free( def );

6
exec.c
View file

@ -993,6 +993,8 @@ void exec( job_t *j )
{
const wchar_t * orig_def;
wchar_t * def=0;
array_list_t *named_arguments;
/*
Calls to function_get_definition might need to
@ -1002,6 +1004,8 @@ void exec( job_t *j )
signal_unblock();
orig_def = function_get_definition( p->argv[0] );
named_arguments = function_get_named_arguments( p->argv[0] );
signal_block();
if( orig_def )
@ -1019,7 +1023,7 @@ void exec( job_t *j )
current_block->param2.function_call_process = p;
current_block->param1.function_call_name = halloc_register( current_block, wcsdup( p->argv[0] ) );
parse_util_set_argv( p->argv+1 );
parse_util_set_argv( p->argv+1, named_arguments );
parser_forbid_function( p->argv[0] );

View file

@ -51,6 +51,9 @@ typedef struct
Line where definition started
*/
int definition_offset;
array_list_t *named_arguments;
/**
Flag for specifying that this function was automatically loaded
@ -164,7 +167,8 @@ void function_destroy()
void function_add( const wchar_t *name,
const wchar_t *val,
const wchar_t *desc,
array_list_t *events )
array_list_t *events,
array_list_t *named_arguments )
{
int i;
wchar_t *cmd_end;
@ -178,6 +182,16 @@ void function_add( const wchar_t *name,
d = halloc( 0, sizeof( function_data_t ) );
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
d->cmd = halloc_wcsdup( d, val );
if( named_arguments )
{
d->named_arguments = al_halloc( d );
for( i=0; i<al_get_count( named_arguments ); i++ )
{
al_push( d->named_arguments, halloc_wcsdup( d, (wchar_t *)al_get( named_arguments, i ) ) );
}
}
cmd_end = d->cmd + wcslen(d->cmd)-1;
@ -242,27 +256,41 @@ void function_remove( const wchar_t *name )
}
}
const wchar_t *function_get_definition( const wchar_t *argv )
const wchar_t *function_get_definition( const wchar_t *name )
{
function_data_t *data;
CHECK( argv, 0 );
CHECK( name, 0 );
load( argv );
data = (function_data_t *)hash_get( &function, argv );
load( name );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return 0;
return data->cmd;
}
const wchar_t *function_get_desc( const wchar_t *argv )
array_list_t *function_get_named_arguments( const wchar_t *name )
{
function_data_t *data;
CHECK( argv, 0 );
CHECK( name, 0 );
load( name );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return 0;
return data->named_arguments;
}
const wchar_t *function_get_desc( const wchar_t *name )
{
function_data_t *data;
CHECK( name, 0 );
load( argv );
data = (function_data_t *)hash_get( &function, argv );
load( name );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return 0;
@ -346,13 +374,13 @@ void function_get_names( array_list_t *list, int get_hidden )
}
const wchar_t *function_get_definition_file( const wchar_t *argv )
const wchar_t *function_get_definition_file( const wchar_t *name )
{
function_data_t *data;
CHECK( argv, 0 );
CHECK( name, 0 );
data = (function_data_t *)hash_get( &function, argv );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return 0;
@ -360,13 +388,13 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
}
int function_get_definition_offset( const wchar_t *argv )
int function_get_definition_offset( const wchar_t *name )
{
function_data_t *data;
CHECK( argv, -1 );
CHECK( name, -1 );
data = (function_data_t *)hash_get( &function, argv );
data = (function_data_t *)hash_get( &function, name );
if( data == 0 )
return -1;

View file

@ -31,7 +31,8 @@ void function_destroy();
void function_add( const wchar_t *name,
const wchar_t *val,
const wchar_t *desc,
array_list_t *events );
array_list_t *events,
array_list_t *named_arguments );
/**
Remove the function with the specified name.
@ -86,4 +87,9 @@ const wchar_t *function_get_definition_file( const wchar_t *name );
*/
int function_get_definition_offset( const wchar_t *name );
/**
Returns a list of all named arguments of the specified function.
*/
array_list_t *function_get_named_arguments( const wchar_t *name );
#endif

View file

@ -1001,7 +1001,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
return reloaded;
}
void parse_util_set_argv( wchar_t **argv )
void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments )
{
if( *argv )
{
@ -1025,6 +1025,23 @@ void parse_util_set_argv( wchar_t **argv )
{
env_set( L"argv", 0, ENV_LOCAL );
}
if( named_arguments )
{
wchar_t **arg;
int i;
for( i=0, arg=argv; i < al_get_count( named_arguments ); i++ )
{
env_set( al_get( named_arguments, i ), *arg, ENV_LOCAL );
if( *arg )
arg++;
}
}
}
wchar_t *parse_util_unescape_wildcards( const wchar_t *str )

View file

@ -138,7 +138,7 @@ int parse_util_unload( const wchar_t *cmd,
Set the argv environment variable to the specified null-terminated
array of strings.
*/
void parse_util_set_argv( wchar_t **argv );
void parse_util_set_argv( wchar_t **argv, array_list_t *named_arguments );
/**
Make a duplicate of the specified string, unescape wildcard