From ee94424b0f4753b9d9a0b075c36d5b65cadafbb4 Mon Sep 17 00:00:00 2001 From: axel Date: Mon, 23 Apr 2007 08:10:33 +1000 Subject: [PATCH] Add the possibility for functions which do not shadow the arguments of the calling function darcs-hash:20070422221033-ac50b-d9544c87d0ddab10f7f503b5a1707292f266efe4.gz --- builtin.c | 62 +++++++++++++++------------------------- exec.c | 4 ++- function.c | 84 +++++++++++++++++++++++++++++++----------------------- function.h | 26 +++++++++++++---- parser.c | 9 ++++++ parser.h | 1 + 6 files changed, 105 insertions(+), 81 deletions(-) diff --git a/builtin.c b/builtin.c index 02360d4ee..52f5c65a7 100644 --- a/builtin.c +++ b/builtin.c @@ -1084,16 +1084,6 @@ static int builtin_functions( wchar_t **argv ) } -typedef struct function_data -{ - wchar_t *name; - wchar_t *description; - array_list_t *events; - array_list_t *named_arguments; -} - function_data_t; - - /** The function builtin, used for providing subroutines. @@ -1108,7 +1098,7 @@ static int builtin_function( wchar_t **argv ) int i; array_list_t *named_arguments=0; wchar_t *name = 0; - + int shadows = 1; woptind=0; @@ -1146,6 +1136,10 @@ static int builtin_function( wchar_t **argv ) L"argument-names", no_argument, 0, 'a' } , + { + L"no-scope-shadowing", no_argument, 0, 'S' + } + , { 0, 0, 0, 0 } @@ -1158,7 +1152,7 @@ static int builtin_function( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"d:s:j:p:v:ha", + L"d:s:j:p:v:haS", long_options, &opt_index ); if( opt == -1 ) @@ -1312,7 +1306,10 @@ static int builtin_function( wchar_t **argv ) named_arguments = al_halloc( current_block ); break; - + case 'S': + shadows = 0; + break; + case 'h': builtin_print_help( argv[0], sb_out ); return STATUS_BUILTIN_OK; @@ -1431,6 +1428,7 @@ static int builtin_function( wchar_t **argv ) d->description=desc?halloc_wcsdup( current_block, desc):0; d->events = events; d->named_arguments = named_arguments; + d->shadows = shadows; for( i=0; itok_pos, - parser_get_job_pos()-current_block->tok_pos ); - - function_add( d->name, - def, - d->description, - d->events, - d->named_arguments ); - - free( def ); - -} - - /** Builtin for ending a block of code, such as a for-loop or an if statement. @@ -2801,7 +2774,18 @@ static int builtin_end( wchar_t **argv ) if( d ) { - builtin_end_add_function_def( d ); + /** + Copy the text from the beginning of the function + until the end command and use as the new definition + for the specified function + */ + + wchar_t *def = wcsndup( parser_get_buffer()+current_block->tok_pos, + parser_get_job_pos()-current_block->tok_pos ); + d->definition = def; + + function_add( d ); + free( def ); } else { diff --git a/exec.c b/exec.c index d42df8089..01d2c929c 100644 --- a/exec.c +++ b/exec.c @@ -994,6 +994,7 @@ void exec( job_t *j ) const wchar_t * orig_def; wchar_t * def=0; array_list_t *named_arguments; + int shadows; /* @@ -1005,6 +1006,7 @@ void exec( job_t *j ) signal_unblock(); orig_def = function_get_definition( p->argv[0] ); named_arguments = function_get_named_arguments( p->argv[0] ); + shadows = function_get_shadows( p->argv[0] ); signal_block(); @@ -1018,7 +1020,7 @@ void exec( job_t *j ) break; } - parser_push_block( FUNCTION_CALL ); + parser_push_block( shadows?FUNCTION_CALL:FUNCTION_CALL_NO_SHADOW ); current_block->param2.function_call_process = p; current_block->param1.function_call_name = halloc_register( current_block, wcsdup( p->argv[0] ) ); diff --git a/function.c b/function.c index 361edd853..0c9c855b6 100644 --- a/function.c +++ b/function.c @@ -60,8 +60,10 @@ typedef struct Flag for specifying that this function was automatically loaded */ int is_autoload; + + int shadows; } - function_data_t; + function_internal_data_t; /** Table containing all functions @@ -83,8 +85,8 @@ static int load( const wchar_t *name ) { int was_autoload = is_autoload; int res; - function_data_t *data; - data = (function_data_t *)hash_get( &function, name ); + function_internal_data_t *data; + data = (function_internal_data_t *)hash_get( &function, name ); if( data && !data->is_autoload ) return 0; @@ -165,46 +167,43 @@ 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 *named_arguments ) +void function_add( function_data_t *data ) { int i; wchar_t *cmd_end; - function_data_t *d; + function_internal_data_t *d; - CHECK( name, ); - CHECK( val, ); + CHECK( data->name, ); + CHECK( data->definition, ); - function_remove( name ); + function_remove( data->name ); - d = halloc( 0, sizeof( function_data_t ) ); + d = halloc( 0, sizeof( function_internal_data_t ) ); 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, data->definition ); - if( named_arguments ) + if( data->named_arguments ) { d->named_arguments = al_halloc( d ); - for( i=0; inamed_arguments ); i++ ) { - al_push( d->named_arguments, halloc_wcsdup( d, (wchar_t *)al_get( named_arguments, i ) ) ); + al_push( d->named_arguments, halloc_wcsdup( d, (wchar_t *)al_get( data->named_arguments, i ) ) ); } } cmd_end = d->cmd + wcslen(d->cmd)-1; - d->desc = desc?halloc_wcsdup( d, desc ):0; + d->desc = data->description?halloc_wcsdup( d, data->description ):0; d->definition_file = intern(reader_current_filename()); d->is_autoload = is_autoload; - - hash_put( &function, intern(name), d ); + d->shadows = data->shadows; - for( i=0; iname), d ); + + for( i=0; ievents ); i++ ) { - event_add_handler( (event_t *)al_get( events, i ) ); + event_add_handler( (event_t *)al_get( data->events, i ) ); } } @@ -225,7 +224,7 @@ void function_remove( const wchar_t *name ) { void *key; void *dv; - function_data_t *d; + function_internal_data_t *d; event_t ev; CHECK( name, ); @@ -235,7 +234,7 @@ void function_remove( const wchar_t *name ) &key, &dv ); - d=(function_data_t *)dv; + d=(function_internal_data_t *)dv; if( !key ) return; @@ -259,12 +258,12 @@ void function_remove( const wchar_t *name ) const wchar_t *function_get_definition( const wchar_t *name ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, 0 ); load( name ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return 0; return data->cmd; @@ -272,26 +271,39 @@ const wchar_t *function_get_definition( const wchar_t *name ) array_list_t *function_get_named_arguments( const wchar_t *name ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, 0 ); load( name ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return 0; return data->named_arguments; } +int function_get_shadows( const wchar_t *name ) +{ + function_internal_data_t *data; + + CHECK( name, 0 ); + + load( name ); + data = (function_internal_data_t *)hash_get( &function, name ); + if( data == 0 ) + return 0; + return data->shadows; +} + const wchar_t *function_get_desc( const wchar_t *name ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, 0 ); load( name ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return 0; @@ -300,13 +312,13 @@ const wchar_t *function_get_desc( const wchar_t *name ) void function_set_desc( const wchar_t *name, const wchar_t *desc ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, ); CHECK( desc, ); load( name ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return; @@ -377,11 +389,11 @@ void function_get_names( array_list_t *list, int get_hidden ) const wchar_t *function_get_definition_file( const wchar_t *name ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, 0 ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return 0; @@ -391,11 +403,11 @@ const wchar_t *function_get_definition_file( const wchar_t *name ) int function_get_definition_offset( const wchar_t *name ) { - function_data_t *data; + function_internal_data_t *data; CHECK( name, -1 ); - data = (function_data_t *)hash_get( &function, name ); + data = (function_internal_data_t *)hash_get( &function, name ); if( data == 0 ) return -1; diff --git a/function.h b/function.h index 56f9c31ac..c4e9030ef 100644 --- a/function.h +++ b/function.h @@ -14,6 +14,21 @@ #include "util.h" +/** + Structure describing a function +*/ +typedef struct function_data +{ + wchar_t *name; + wchar_t *description; + wchar_t *definition; + array_list_t *events; + array_list_t *named_arguments; + int shadows; +} + function_data_t; + + /** Initialize function data */ @@ -28,11 +43,7 @@ void function_destroy(); Add an function. The parameters values are copied and should be freed by the caller. */ -void function_add( const wchar_t *name, - const wchar_t *val, - const wchar_t *desc, - array_list_t *events, - array_list_t *named_arguments ); +void function_add( function_data_t *data ); /** Remove the function with the specified name. @@ -92,4 +103,9 @@ int function_get_definition_offset( const wchar_t *name ); */ array_list_t *function_get_named_arguments( const wchar_t *name ); +/** + Returns whether this function shadows variables of the underlying function +*/ +int function_get_shadows( const wchar_t *name ); + #endif diff --git a/parser.c b/parser.c index 947d9fa31..c115aafb0 100644 --- a/parser.c +++ b/parser.c @@ -213,6 +213,11 @@ The fish parser. Contains functions for parsing and evaluating code. */ #define FUNCTION_CALL_BLOCK N_( L"function invocation block" ) +/** + Function invocation block description +*/ +#define FUNCTION_CALL_NO_SHADOW_BLOCK N_( L"function invocation block with no variable shadowing" ) + /** Switch block description @@ -309,6 +314,10 @@ const static struct block_lookup_entry block_lookup[]= FUNCTION_CALL, 0, FUNCTION_CALL_BLOCK } , + { + FUNCTION_CALL_NO_SHADOW, 0, FUNCTION_CALL_NO_SHADOW_BLOCK + } + , { SWITCH, L"switch", SWITCH_BLOCK } diff --git a/parser.h b/parser.h index 1dc3a02c4..0c82f2aae 100644 --- a/parser.h +++ b/parser.h @@ -120,6 +120,7 @@ enum block_type IF, /**< If block */ FUNCTION_DEF, /**< Function definition block */ FUNCTION_CALL, /**< Function invocation block */ + FUNCTION_CALL_NO_SHADOW, /**< Function invocation block with no variable shadowing */ SWITCH, /**< Switch block */ FAKE, /**< Fake block */ SUBST, /**< Command substitution scope */