aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2006-09-18 10:15:18 +1000
committerGravatar axel <axel@liljencrantz.se>2006-09-18 10:15:18 +1000
commit810faacd72fc330cfa572739a22e901087a94650 (patch)
tree782cad06fa8351be563455ad8be172b56bd75ac2
parent6be3807caecf823994290c74865cbaefc212e8a5 (diff)
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
-rw-r--r--parser.c113
1 files changed, 103 insertions, 10 deletions
diff --git a/parser.c b/parser.c
index 4e339968..3c9d4c89 100644
--- a/parser.c
+++ b/parser.c
@@ -128,6 +128,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
*/
#define INVALID_ELSE_ERR_MSG _( L"'else' builtin not inside of if block" )
@@ -3207,6 +3212,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
*/
if( contains_str( cmd, L"break", L"continue", (void *)0 ) )
@@ -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;
}