Add the possibility for functions which do not shadow the arguments of the calling function

darcs-hash:20070422221033-ac50b-d9544c87d0ddab10f7f503b5a1707292f266efe4.gz
This commit is contained in:
axel 2007-04-23 08:10:33 +10:00
parent 2b7535bb51
commit ee94424b0f
6 changed files with 105 additions and 81 deletions

View file

@ -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. The function builtin, used for providing subroutines.
@ -1108,7 +1098,7 @@ static int builtin_function( wchar_t **argv )
int i; int i;
array_list_t *named_arguments=0; array_list_t *named_arguments=0;
wchar_t *name = 0; wchar_t *name = 0;
int shadows = 1;
woptind=0; woptind=0;
@ -1146,6 +1136,10 @@ static int builtin_function( wchar_t **argv )
L"argument-names", no_argument, 0, 'a' L"argument-names", no_argument, 0, 'a'
} }
, ,
{
L"no-scope-shadowing", no_argument, 0, 'S'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -1158,7 +1152,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:ha", L"d:s:j:p:v:haS",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -1312,7 +1306,10 @@ static int builtin_function( wchar_t **argv )
named_arguments = al_halloc( current_block ); named_arguments = al_halloc( current_block );
break; break;
case 'S':
shadows = 0;
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;
@ -1431,6 +1428,7 @@ static int builtin_function( wchar_t **argv )
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; d->named_arguments = named_arguments;
d->shadows = shadows;
for( i=0; i<al_get_count( events ); i++ ) for( i=0; i<al_get_count( events ); i++ )
{ {
@ -2691,31 +2689,6 @@ static int builtin_begin( wchar_t **argv )
return proc_get_last_status(); return proc_get_last_status();
} }
/**
Define the function specified by the function_data_t structure.
*/
static void builtin_end_add_function_def( function_data_t *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 );
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. 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 ) 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 else
{ {

4
exec.c
View file

@ -994,6 +994,7 @@ 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; array_list_t *named_arguments;
int shadows;
/* /*
@ -1005,6 +1006,7 @@ 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] ); named_arguments = function_get_named_arguments( p->argv[0] );
shadows = function_get_shadows( p->argv[0] );
signal_block(); signal_block();
@ -1018,7 +1020,7 @@ void exec( job_t *j )
break; 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->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] ) );

View file

@ -60,8 +60,10 @@ typedef struct
Flag for specifying that this function was automatically loaded Flag for specifying that this function was automatically loaded
*/ */
int is_autoload; int is_autoload;
int shadows;
} }
function_data_t; function_internal_data_t;
/** /**
Table containing all functions Table containing all functions
@ -83,8 +85,8 @@ static int load( const wchar_t *name )
{ {
int was_autoload = is_autoload; int was_autoload = is_autoload;
int res; int res;
function_data_t *data; function_internal_data_t *data;
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data && !data->is_autoload ) if( data && !data->is_autoload )
return 0; return 0;
@ -165,46 +167,43 @@ void function_destroy()
} }
void function_add( const wchar_t *name, void function_add( function_data_t *data )
const wchar_t *val,
const wchar_t *desc,
array_list_t *events,
array_list_t *named_arguments )
{ {
int i; int i;
wchar_t *cmd_end; wchar_t *cmd_end;
function_data_t *d; function_internal_data_t *d;
CHECK( name, ); CHECK( data->name, );
CHECK( val, ); 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->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 ); d->named_arguments = al_halloc( d );
for( i=0; i<al_get_count( named_arguments ); i++ ) for( i=0; i<al_get_count( data->named_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; 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->definition_file = intern(reader_current_filename());
d->is_autoload = is_autoload; d->is_autoload = is_autoload;
d->shadows = data->shadows;
hash_put( &function, intern(name), d );
for( i=0; i<al_get_count( events ); i++ ) hash_put( &function, intern(data->name), d );
for( i=0; i<al_get_count( data->events ); 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 *key;
void *dv; void *dv;
function_data_t *d; function_internal_data_t *d;
event_t ev; event_t ev;
CHECK( name, ); CHECK( name, );
@ -235,7 +234,7 @@ void function_remove( const wchar_t *name )
&key, &key,
&dv ); &dv );
d=(function_data_t *)dv; d=(function_internal_data_t *)dv;
if( !key ) if( !key )
return; return;
@ -259,12 +258,12 @@ void function_remove( const wchar_t *name )
const wchar_t *function_get_definition( 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 ); CHECK( name, 0 );
load( name ); load( name );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 0; return 0;
return data->cmd; 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 ) array_list_t *function_get_named_arguments( const wchar_t *name )
{ {
function_data_t *data; function_internal_data_t *data;
CHECK( name, 0 ); CHECK( name, 0 );
load( name ); load( name );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 0; return 0;
return data->named_arguments; 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 ) const wchar_t *function_get_desc( const wchar_t *name )
{ {
function_data_t *data; function_internal_data_t *data;
CHECK( name, 0 ); CHECK( name, 0 );
load( name ); load( name );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 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 ) void function_set_desc( const wchar_t *name, const wchar_t *desc )
{ {
function_data_t *data; function_internal_data_t *data;
CHECK( name, ); CHECK( name, );
CHECK( desc, ); CHECK( desc, );
load( name ); load( name );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return; 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 ) const wchar_t *function_get_definition_file( const wchar_t *name )
{ {
function_data_t *data; function_internal_data_t *data;
CHECK( name, 0 ); CHECK( name, 0 );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return 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 ) int function_get_definition_offset( const wchar_t *name )
{ {
function_data_t *data; function_internal_data_t *data;
CHECK( name, -1 ); CHECK( name, -1 );
data = (function_data_t *)hash_get( &function, name ); data = (function_internal_data_t *)hash_get( &function, name );
if( data == 0 ) if( data == 0 )
return -1; return -1;

View file

@ -14,6 +14,21 @@
#include "util.h" #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 Initialize function data
*/ */
@ -28,11 +43,7 @@ void function_destroy();
Add an function. The parameters values are copied and should be Add an function. The parameters values are copied and should be
freed by the caller. freed by the caller.
*/ */
void function_add( const wchar_t *name, void function_add( function_data_t *data );
const wchar_t *val,
const wchar_t *desc,
array_list_t *events,
array_list_t *named_arguments );
/** /**
Remove the function with the specified name. 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 ); 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 #endif

View file

@ -213,6 +213,11 @@ The fish parser. Contains functions for parsing and evaluating code.
*/ */
#define FUNCTION_CALL_BLOCK N_( L"function invocation block" ) #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 Switch block description
@ -309,6 +314,10 @@ const static struct block_lookup_entry block_lookup[]=
FUNCTION_CALL, 0, FUNCTION_CALL_BLOCK FUNCTION_CALL, 0, FUNCTION_CALL_BLOCK
} }
, ,
{
FUNCTION_CALL_NO_SHADOW, 0, FUNCTION_CALL_NO_SHADOW_BLOCK
}
,
{ {
SWITCH, L"switch", SWITCH_BLOCK SWITCH, L"switch", SWITCH_BLOCK
} }

View file

@ -120,6 +120,7 @@ enum block_type
IF, /**< If block */ IF, /**< If block */
FUNCTION_DEF, /**< Function definition block */ FUNCTION_DEF, /**< Function definition block */
FUNCTION_CALL, /**< Function invocation block */ FUNCTION_CALL, /**< Function invocation block */
FUNCTION_CALL_NO_SHADOW, /**< Function invocation block with no variable shadowing */
SWITCH, /**< Switch block */ SWITCH, /**< Switch block */
FAKE, /**< Fake block */ FAKE, /**< Fake block */
SUBST, /**< Command substitution scope */ SUBST, /**< Command substitution scope */