mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-01-31 15:56:15 +08:00
No semicolon required after else/begin
darcs-hash:20050925112542-ac50b-6cdba042b3f4de89c3f23c3d5e115608ec2c54b8.gz
This commit is contained in:
parent
fcc980a519
commit
f1f5904fe1
91
parser.c
91
parser.c
|
@ -266,18 +266,29 @@ wchar_t *parser_get_block_desc( int block )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int parser_skip_arguments( const wchar_t *cmd )
|
||||||
|
{
|
||||||
|
|
||||||
|
return contains_str( cmd,
|
||||||
|
L"else",
|
||||||
|
L"begin",
|
||||||
|
0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int parser_is_subcommand( const wchar_t *cmd )
|
int parser_is_subcommand( const wchar_t *cmd )
|
||||||
{
|
{
|
||||||
return contains_str( cmd,
|
return parser_skip_arguments( cmd ) ||
|
||||||
L"command",
|
contains_str( cmd,
|
||||||
L"builtin",
|
L"command",
|
||||||
L"while",
|
L"builtin",
|
||||||
L"exec",
|
L"while",
|
||||||
L"if",
|
L"exec",
|
||||||
L"and",
|
L"if",
|
||||||
L"or",
|
L"and",
|
||||||
L"not",
|
L"or",
|
||||||
0 );
|
L"not",
|
||||||
|
0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1522,7 +1533,17 @@ static int parse_job( process_t *p,
|
||||||
else tok_next( tok );
|
else tok_next( tok );
|
||||||
|
|
||||||
if( !error_code )
|
if( !error_code )
|
||||||
parse_job_main_loop( p, j, tok, &args );
|
{
|
||||||
|
if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(&args, 0) ) )
|
||||||
|
{
|
||||||
|
p->argv = list_to_char_arr( &args );
|
||||||
|
// tok_next(tok);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parse_job_main_loop( p, j, tok, &args );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( error_code )
|
if( error_code )
|
||||||
{
|
{
|
||||||
|
@ -1955,13 +1976,20 @@ int parser_test( wchar_t * buff,
|
||||||
require_additional_commands--;
|
require_additional_commands--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Decrement block count on end command
|
||||||
|
*/
|
||||||
if( wcscmp(tok_last(&tok), L"end")==0)
|
if( wcscmp(tok_last(&tok), L"end")==0)
|
||||||
{
|
{
|
||||||
tok_next( &tok );
|
tok_next( &tok );
|
||||||
count--;
|
count--;
|
||||||
tok_set_pos( &tok, mark );
|
tok_set_pos( &tok, mark );
|
||||||
}
|
}
|
||||||
else if( parser_is_block( tok_last(&tok) ) )
|
|
||||||
|
/*
|
||||||
|
Handle block commands
|
||||||
|
*/
|
||||||
|
if( parser_is_block( tok_last(&tok) ) )
|
||||||
{
|
{
|
||||||
if( count >= BLOCK_MAX_COUNT )
|
if( count >= BLOCK_MAX_COUNT )
|
||||||
{
|
{
|
||||||
|
@ -1980,6 +2008,8 @@ int parser_test( wchar_t * buff,
|
||||||
block_type[count] = IF;
|
block_type[count] = IF;
|
||||||
else if( wcscmp( tok_last(&tok), L"function") == 0 )
|
else if( wcscmp( tok_last(&tok), L"function") == 0 )
|
||||||
block_type[count] = FUNCTION_DEF;
|
block_type[count] = FUNCTION_DEF;
|
||||||
|
else if( wcscmp( tok_last(&tok), L"begin") == 0 )
|
||||||
|
block_type[count] = BEGIN;
|
||||||
else
|
else
|
||||||
block_type[count] = -1;
|
block_type[count] = -1;
|
||||||
|
|
||||||
|
@ -1993,12 +2023,21 @@ int parser_test( wchar_t * buff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parser_is_subcommand( tok_last( &tok ) ) )
|
/*
|
||||||
|
If parser_is_subcommand is true, the command
|
||||||
|
accepts a second command as it's first
|
||||||
|
argument. If parser_skip_arguments is true, the
|
||||||
|
second argument is optional.
|
||||||
|
*/
|
||||||
|
if( parser_is_subcommand( tok_last( &tok ) ) && !parser_skip_arguments(tok_last( &tok ) ) )
|
||||||
{
|
{
|
||||||
needs_cmd = 1;
|
needs_cmd = 1;
|
||||||
had_cmd = 0;
|
had_cmd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The short circut commands requires _two_ additional commands.
|
||||||
|
*/
|
||||||
if( contains_str( tok_last( &tok ),
|
if( contains_str( tok_last( &tok ),
|
||||||
L"or",
|
L"or",
|
||||||
L"and",
|
L"and",
|
||||||
|
@ -2019,7 +2058,11 @@ int parser_test( wchar_t * buff,
|
||||||
require_additional_commands=2;
|
require_additional_commands=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
There are a lot of situations where pipelines
|
||||||
|
are forbidden, inclusing when using the exec
|
||||||
|
builtin.
|
||||||
|
*/
|
||||||
if( parser_is_pipe_forbidden( tok_last( &tok ) ) )
|
if( parser_is_pipe_forbidden( tok_last( &tok ) ) )
|
||||||
{
|
{
|
||||||
if( is_pipeline )
|
if( is_pipeline )
|
||||||
|
@ -2037,6 +2080,9 @@ int parser_test( wchar_t * buff,
|
||||||
forbid_pipeline = 1;
|
forbid_pipeline = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test that the case builtin is only used in a switch block
|
||||||
|
*/
|
||||||
if( wcscmp( L"case", tok_last( &tok ) )==0 )
|
if( wcscmp( L"case", tok_last( &tok ) )==0 )
|
||||||
{
|
{
|
||||||
if( !count || block_type[count-1]!=SWITCH )
|
if( !count || block_type[count-1]!=SWITCH )
|
||||||
|
@ -2055,8 +2101,12 @@ int parser_test( wchar_t * buff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( wcscmp( L"break", tok_last( &tok ) )==0 ||
|
|
||||||
wcscmp( L"continue", tok_last( &tok ) )==0)
|
/*
|
||||||
|
Test that break and continue are only used in loop blocks
|
||||||
|
*/
|
||||||
|
if( wcscmp( L"break", tok_last( &tok ) )==0 ||
|
||||||
|
wcscmp( L"continue", tok_last( &tok ) )==0)
|
||||||
{
|
{
|
||||||
int found_loop=0;
|
int found_loop=0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -2083,7 +2133,11 @@ int parser_test( wchar_t * buff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( wcscmp( L"else", tok_last( &tok ) )==0 )
|
|
||||||
|
/*
|
||||||
|
Test that else is only used in an if-block
|
||||||
|
*/
|
||||||
|
if( wcscmp( L"else", tok_last( &tok ) )==0 )
|
||||||
{
|
{
|
||||||
if( !count || block_type[count-1]!=IF )
|
if( !count || block_type[count-1]!=IF )
|
||||||
{
|
{
|
||||||
|
@ -2099,6 +2153,9 @@ int parser_test( wchar_t * buff,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test that end is not used when not inside a blovk
|
||||||
|
*/
|
||||||
if( count < 0 )
|
if( count < 0 )
|
||||||
{
|
{
|
||||||
err = 1;
|
err = 1;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user