Make sure that syntax validator allows use of 'break' and 'continue' with --help even outside of loops, and make sure 'return' is only used in function definitions.

darcs-hash:20060918001518-ac50b-78977cbd17e4edce8d1b7d4c5426f478d42392af.gz
This commit is contained in:
axel 2006-09-18 10:15:18 +10:00
parent 6be3807cae
commit 810faacd72

113
parser.c
View file

@ -127,6 +127,11 @@ The fish parser. Contains functions for parsing code.
*/ */
#define INVALID_LOOP_ERR_MSG _( L"Loop control command while not inside of loop" ) #define INVALID_LOOP_ERR_MSG _( L"Loop control command while not inside of loop" )
/**
Error when using return builtin outside of function definition
*/
#define INVALID_RETURN_ERR_MSG _( L"'return' command command outside of function definition" )
/** /**
Error when using else builtin outside of if block Error when using else builtin outside of if block
*/ */
@ -3206,6 +3211,67 @@ int parser_test( const wchar_t * buff,
} }
} }
/*
Test that the return bultin is only used within function definitions
*/
if( wcscmp( cmd, L"return" ) == 0 )
{
int found_func=0;
int i;
for( i=count-1; i>=0; i-- )
{
if( block_type[i]==FUNCTION_DEF )
{
found_func=1;
break;
}
}
if( !found_func )
{
/*
Peek to see if the next argument is
--help, in which case we'll allow it to
show the help.
*/
wchar_t *first_arg;
int old_pos = tok_get_pos( &tok );
int is_help = 0;
tok_next( &tok );
if( tok_last_type( &tok ) == TOK_STRING )
{
first_arg = expand_one( context,
wcsdup( tok_last( &tok ) ),
EXPAND_SKIP_CMDSUBST);
if( first_arg && parser_is_help( first_arg, 3) )
{
is_help = 1;
}
}
tok_set_pos( &tok, old_pos );
if( !is_help )
{
err=1;
if( out )
{
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
INVALID_RETURN_ERR_MSG );
print_errors( out, prefix );
}
}
}
}
/* /*
Test that break and continue are only used within loop blocks Test that break and continue are only used within loop blocks
*/ */
@ -3225,16 +3291,45 @@ int parser_test( const wchar_t * buff,
if( !found_loop ) if( !found_loop )
{ {
err=1; /*
Peek to see if the next argument is
--help, in which case we'll allow it to
show the help.
*/
if( out ) wchar_t *first_arg;
int old_pos = tok_get_pos( &tok );
int is_help = 0;
tok_next( &tok );
if( tok_last_type( &tok ) == TOK_STRING )
{ {
error( SYNTAX_ERROR, first_arg = expand_one( context,
tok_get_pos( &tok ), wcsdup( tok_last( &tok ) ),
INVALID_LOOP_ERR_MSG ); EXPAND_SKIP_CMDSUBST);
print_errors( out, prefix );
if( first_arg && parser_is_help( first_arg, 3 ) )
{
is_help = 1;
}
}
tok_set_pos( &tok, old_pos );
if( !is_help )
{
err=1;
if( out )
{
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
INVALID_LOOP_ERR_MSG );
print_errors( out, prefix );
}
} }
} }
} }
/* /*
@ -3494,10 +3589,8 @@ int parser_test( const wchar_t * buff,
} }
} }
if( had_cmd ) had_cmd = 0;
{
had_cmd = 0;
}
break; break;
} }