From 4d6751c2740298709d291dde304d4ee7a9330944 Mon Sep 17 00:00:00 2001 From: axel Date: Tue, 17 Apr 2007 06:06:11 +1000 Subject: [PATCH] =?UTF-8?q?Allow=20named=20arguments=20to=20function=20ins?= =?UTF-8?q?tead=20of=20only=20$argv.=20Philip=20Ganchev=20once=20suggested?= =?UTF-8?q?=20this,=20and=20it=20was=20suggested=20again=20by=20Egil=20M?= =?UTF-8?q?=C3=B6ller.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit darcs-hash:20070416200611-ac50b-5eb42c94a65a4e72cae12cd9c04424bdc3b2b4f8.gz --- builtin.c | 56 ++++++++++++++++++++++++++++++++++++++++-------- exec.c | 6 +++++- function.c | 60 ++++++++++++++++++++++++++++++++++++++-------------- function.h | 8 ++++++- parse_util.c | 19 ++++++++++++++++- parse_util.h | 2 +- 6 files changed, 122 insertions(+), 29 deletions(-) diff --git a/builtin.c b/builtin.c index 4e30a51f9..dec4db22c 100644 --- a/builtin.c +++ b/builtin.c @@ -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; iparam1.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 ); diff --git a/exec.c b/exec.c index 9b0e1cc6c..72826243c 100644 --- a/exec.c +++ b/exec.c @@ -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] ); diff --git a/function.c b/function.c index 33263385f..23a942cf2 100644 --- a/function.c +++ b/function.c @@ -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; inamed_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; diff --git a/function.h b/function.h index e1af4106f..56f9c31ac 100644 --- a/function.h +++ b/function.h @@ -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 diff --git a/parse_util.c b/parse_util.c index fba126fb8..7a767ba0b 100644 --- a/parse_util.c +++ b/parse_util.c @@ -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 ) diff --git a/parse_util.h b/parse_util.h index 2b1aec538..796669240 100644 --- a/parse_util.h +++ b/parse_util.h @@ -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