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

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

6
exec.c

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

@ -51,6 +51,9 @@ typedef struct
Line where definition started Line where definition started
*/ */
int definition_offset; int definition_offset;
array_list_t *named_arguments;
/** /**
Flag for specifying that this function was automatically loaded Flag for specifying that this function was automatically loaded
@ -164,7 +167,8 @@ void function_destroy()
void function_add( const wchar_t *name, void function_add( const wchar_t *name,
const wchar_t *val, const wchar_t *val,
const wchar_t *desc, const wchar_t *desc,
array_list_t *events ) array_list_t *events,
array_list_t *named_arguments )
{ {
int i; int i;
wchar_t *cmd_end; wchar_t *cmd_end;
@ -178,6 +182,16 @@ void function_add( const wchar_t *name,
d = halloc( 0, sizeof( function_data_t ) ); d = halloc( 0, sizeof( function_data_t ) );
d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1; d->definition_offset = parse_util_lineno( parser_get_buffer(), current_block->tok_pos )-1;
d->cmd = halloc_wcsdup( d, val ); 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; 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; function_data_t *data;
CHECK( argv, 0 ); CHECK( name, 0 );
load( argv ); load( name );
data = (function_data_t *)hash_get( &function, argv ); data = (function_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 0; return 0;
return data->cmd; 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; 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 ); load( name );
data = (function_data_t *)hash_get( &function, argv ); data = (function_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 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; 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 ) if( data == 0 )
return 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; 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 ) if( data == 0 )
return -1; return -1;

@ -31,7 +31,8 @@ void function_destroy();
void function_add( const wchar_t *name, void function_add( const wchar_t *name,
const wchar_t *val, const wchar_t *val,
const wchar_t *desc, const wchar_t *desc,
array_list_t *events ); array_list_t *events,
array_list_t *named_arguments );
/** /**
Remove the function with the specified name. 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 ); 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 #endif

@ -1001,7 +1001,7 @@ static int parse_util_load_internal( const wchar_t *cmd,
return reloaded; 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 ) if( *argv )
{ {
@ -1025,6 +1025,23 @@ void parse_util_set_argv( wchar_t **argv )
{ {
env_set( L"argv", 0, ENV_LOCAL ); 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 ) wchar_t *parse_util_unescape_wildcards( const wchar_t *str )

@ -138,7 +138,7 @@ int parse_util_unload( const wchar_t *cmd,
Set the argv environment variable to the specified null-terminated Set the argv environment variable to the specified null-terminated
array of strings. 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 Make a duplicate of the specified string, unescape wildcard