From 810faacd72fc330cfa572739a22e901087a94650 Mon Sep 17 00:00:00 2001 From: axel Date: Mon, 18 Sep 2006 10:15:18 +1000 Subject: [PATCH] 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 --- parser.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 10 deletions(-) diff --git a/parser.c b/parser.c index 4e339968f..3c9d4c89d 100644 --- a/parser.c +++ b/parser.c @@ -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" ) +/** + 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 */ @@ -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 */ @@ -3225,16 +3291,45 @@ int parser_test( const wchar_t * buff, 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, - tok_get_pos( &tok ), - INVALID_LOOP_ERR_MSG ); - print_errors( out, prefix ); + 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_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; }