Merge remote branch 'origin/otherchirps-dev'

This commit is contained in:
Grissiom 2010-09-19 14:12:30 +08:00
commit 1b9dd0c75f
4 changed files with 118 additions and 7 deletions

View file

@ -1252,6 +1252,7 @@ static int builtin_functions( wchar_t **argv )
int show_hidden=0; int show_hidden=0;
int res = STATUS_BUILTIN_OK; int res = STATUS_BUILTIN_OK;
int query = 0; int query = 0;
int copy = 0;
woptind=0; woptind=0;
@ -1282,6 +1283,10 @@ static int builtin_functions( wchar_t **argv )
L"query", no_argument, 0, 'q' L"query", no_argument, 0, 'q'
} }
, ,
{
L"copy", no_argument, 0, 'c'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -1294,7 +1299,7 @@ static int builtin_functions( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"ed:nahq", L"ed:nahqc",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -1305,10 +1310,10 @@ static int builtin_functions( wchar_t **argv )
case 0: case 0:
if(long_options[opt_index].flag != 0) if(long_options[opt_index].flag != 0)
break; break;
sb_printf( sb_err, sb_printf( sb_err,
BUILTIN_ERR_UNKNOWN, BUILTIN_ERR_UNKNOWN,
argv[0], argv[0],
long_options[opt_index].name ); long_options[opt_index].name );
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
@ -1338,6 +1343,10 @@ static int builtin_functions( wchar_t **argv )
query = 1; query = 1;
break; break;
case 'c':
copy = 1;
break;
case '?': case '?':
builtin_unknown_option( argv[0], argv[woptind-1] ); builtin_unknown_option( argv[0], argv[woptind-1] );
return STATUS_BUILTIN_ERROR; return STATUS_BUILTIN_ERROR;
@ -1347,9 +1356,9 @@ static int builtin_functions( wchar_t **argv )
} }
/* /*
Erase, desc, query and list are mutually exclusive Erase, desc, query, copy and list are mutually exclusive
*/ */
if( (erase + (!!desc) + list + query) > 1 ) if( (erase + (!!desc) + list + query + copy) > 1 )
{ {
sb_printf( sb_err, sb_printf( sb_err,
_( L"%ls: Invalid combination of options\n" ), _( L"%ls: Invalid combination of options\n" ),
@ -1434,6 +1443,61 @@ static int builtin_functions( wchar_t **argv )
al_destroy( &names ); al_destroy( &names );
return STATUS_BUILTIN_OK; return STATUS_BUILTIN_OK;
} }
else if( copy )
{
wchar_t *current_func;
wchar_t *new_func;
if( argc-woptind != 2 )
{
sb_printf( sb_err,
_( L"%ls: Expected exactly two names (current function name, and new function name)\n" ),
argv[0] );
builtin_print_help ( argv[0], sb_err );
return STATUS_BUILTIN_ERROR;
}
current_func = argv[woptind];
new_func = argv[woptind+1];
if( !function_exists( current_func ) )
{
sb_printf( sb_err,
_( L"%ls: Function '%ls' does not exist\n" ),
argv[0],
current_func );
builtin_print_help( argv[0], sb_err );
return STATUS_BUILTIN_ERROR;
}
if( (wcsfuncname( new_func ) != 0) || parser_keywords_is_reserved( new_func ) )
{
sb_printf( sb_err,
_( L"%ls: Illegal function name '%ls'\n"),
argv[0],
new_func );
builtin_print_help( argv[0], sb_err );
return STATUS_BUILTIN_ERROR;
}
// keep things simple: don't allow existing names to be copy targets.
if( function_exists( new_func ) )
{
sb_printf( sb_err,
_( L"%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" ),
argv[0],
new_func,
current_func );
builtin_print_help( argv[0], sb_err );
return STATUS_BUILTIN_ERROR;
}
if( function_copy( current_func, new_func ) )
return STATUS_BUILTIN_OK;
return STATUS_BUILTIN_ERROR;
}
for( i=woptind; i<argc; i++ ) for( i=woptind; i<argc; i++ )
{ {

View file

@ -8,6 +8,7 @@
This builtin command is used to print or erase functions. This builtin command is used to print or erase functions.
- <code>-a</code> or <code>--all</code> list all functions, even those whose name start with an underscore. - <code>-a</code> or <code>--all</code> list all functions, even those whose name start with an underscore.
- <code>-c OLDNAME NEWNAME</code> or <code>--copy OLDNAME NEWNAME</code> creates a new function named NEWNAME, using the definition of the OLDNAME function.
- <code>-d DESCRIPTION</code> or <code>--description=DESCRIPTION</code> change the description of this function - <code>-d DESCRIPTION</code> or <code>--description=DESCRIPTION</code> change the description of this function
- <code>-e</code> or <code>--erase</code> causes the specified functions to be erased. - <code>-e</code> or <code>--erase</code> causes the specified functions to be erased.
- <code>-h</code> or <code>--help</code> display a help message and exit - <code>-h</code> or <code>--help</code> display a help message and exit
@ -23,5 +24,8 @@ Automatically loaded functions can not be removed using functions
-e. Either remove the definition file or change the -e. Either remove the definition file or change the
$fish_function_path variable to remove autoloaded functions. $fish_function_path variable to remove autoloaded functions.
Function copies, created with -c, will not have any event/signal/on-exit
notifications that the original may have had.
The exit status of the functions builtin is the number functions The exit status of the functions builtin is the number functions
specified in the argument list that do not exist. specified in the argument list that do not exist.

View file

@ -218,6 +218,43 @@ void function_add( function_data_t *data )
} }
int function_copy( const wchar_t *name, const wchar_t *new_name )
{
int i;
function_internal_data_t *d, *orig_d;
CHECK( name, 0 );
CHECK( new_name, 0 );
orig_d = (function_internal_data_t *)hash_get(&function, name);
if( !orig_d )
return 0;
d = halloc(0, sizeof( function_internal_data_t ) );
d->definition_offset = orig_d->definition_offset;
d->definition = halloc_wcsdup( d, orig_d->definition );
if( orig_d->named_arguments )
{
d->named_arguments = al_halloc( d );
for( i=0; i<al_get_count( orig_d->named_arguments ); i++ )
{
al_push( d->named_arguments, halloc_wcsdup( d, (wchar_t *)al_get( orig_d->named_arguments, i ) ) );
}
d->description = orig_d->description?halloc_wcsdup(d, orig_d->description):0;
d->shadows = orig_d->shadows;
// This new instance of the function shouldn't be tied to the def
// file of the original.
d->definition_file = 0;
d->is_autoload = 0;
}
hash_put( &function, intern(new_name), d );
return 1;
}
int function_exists( const wchar_t *cmd ) int function_exists( const wchar_t *cmd )
{ {

View file

@ -131,4 +131,10 @@ array_list_t *function_get_named_arguments( const wchar_t *name );
*/ */
int function_get_shadows( const wchar_t *name ); int function_get_shadows( const wchar_t *name );
/**
Creates a new function using the same definition as the specified function.
Returns non-zero if copy is successful.
*/
int function_copy( const wchar_t *name, const wchar_t *new_name );
#endif #endif