From a1a2773cbff6a124058d8cb7f2ff36376ecf7f64 Mon Sep 17 00:00:00 2001 From: axel Date: Fri, 2 Jun 2006 12:15:17 +1000 Subject: [PATCH] Make sure code validation error output for e.g. the complete builtin can be redirected, and that it has the prefix 'complete', not 'fish' darcs-hash:20060602021517-ac50b-5e566aefbd1c9bcb3a5f11f9fc1125d8c1d9e936.gz --- builtin.c | 2 +- builtin_complete.c | 13 +++-- parser.c | 139 ++++++++++++++++++++++++++------------------- parser.h | 4 +- reader.c | 36 +++++++----- 5 files changed, 112 insertions(+), 82 deletions(-) diff --git a/builtin.c b/builtin.c index f092a8a34..292e3fd9f 100644 --- a/builtin.c +++ b/builtin.c @@ -2502,7 +2502,7 @@ static int builtin_end( wchar_t **argv ) //fwprintf( stderr, L"Function: %ls\n", def ); - if( !is_interactive || !parser_test( def, 1 ) ) + if( !is_interactive || !parser_test( def, sb_err, argv[0] ) ) { function_add( current_block->param1.function_name, def, diff --git a/builtin_complete.c b/builtin_complete.c index 3e4268c66..3a1e6c05b 100644 --- a/builtin_complete.c +++ b/builtin_complete.c @@ -30,7 +30,10 @@ const static wchar_t *temporary_buffer; /* builtin_complete_* are a set of rather silly looping functions that make sure that all the proper combinations of complete_add or - complete_remove get called. + complete_remove get called. This is needed since complete allows you + to specify multiple switches on a single commandline, like 'complete + -s a -s b -s c', but the complete_add function only accepts one + short switch and one long switch. */ static void builtin_complete_add2( const wchar_t *cmd, @@ -455,14 +458,14 @@ int builtin_complete( wchar_t **argv ) { if( condition && wcslen( condition ) ) { - if( parser_test( condition, 0 ) ) + if( parser_test( condition, 0, 0 ) ) { sb_printf( sb_err, L"%ls: Condition '%ls' contained a syntax error\n", argv[0], condition ); - parser_test( condition, 1 ); + parser_test( condition, sb_err, argv[0] ); res = 1; } @@ -473,14 +476,14 @@ int builtin_complete( wchar_t **argv ) { if( comp && wcslen( comp ) ) { - if( parser_test_args( comp, 0 ) ) + if( parser_test_args( comp, 0, 0 ) ) { sb_printf( sb_err, L"%ls: Completion '%ls' contained a syntax error\n", argv[0], comp ); - parser_test_args( comp, 1 ); + parser_test_args( comp, sb_err, argv[0] ); res = 1; } diff --git a/parser.c b/parser.c index b0aef8e30..57565cf42 100644 --- a/parser.c +++ b/parser.c @@ -919,23 +919,40 @@ void parser_destroy() /** Print error message if an error has occured while parsing */ -static void print_errors() +static void print_errors( string_buffer_t *target, const wchar_t *prefix ) { if( error_code ) { int tmp; - debug( 0, L"%ls", err_str ); + sb_printf( target, L"%ls: %ls\n", prefix, err_str ); tmp = current_tokenizer_pos; current_tokenizer_pos = err_pos; - fwprintf( stderr, L"%ls", parser_current_line() ); + sb_printf( target, L"%ls", parser_current_line() ); current_tokenizer_pos=tmp; } } +static void print_errors_stderr() +{ + if( error_code ) + { + debug( 0, L"%ls", err_str ); + int tmp; + + tmp = current_tokenizer_pos; + current_tokenizer_pos = err_pos; + + fwprintf( stderr, L"%ls", parser_current_line() ); + + current_tokenizer_pos=tmp; + } + +} + int eval_args( const wchar_t *line, array_list_t *args ) { tokenizer tok; @@ -1004,8 +1021,9 @@ int eval_args( const wchar_t *line, array_list_t *args ) } } } + + print_errors_stderr(); - print_errors(); tok_destroy( &tok ); current_tokenizer=previous_tokenizer; @@ -2516,7 +2534,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) parser_pop_block(); } - print_errors(); + print_errors_stderr(); tok_destroy( current_tokenizer ); free( current_tokenizer ); @@ -2565,7 +2583,7 @@ static int parser_get_block_type( const wchar_t *cmd ) } -static int parser_test_argument( const wchar_t *arg, int babble, int offset ) +static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ) { wchar_t *unesc; wchar_t *pos; @@ -2584,12 +2602,12 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) { case -1: err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, offset, L"Mismatched parans" ); - print_errors(); + print_errors( out, prefix); } free( arg_cpy ); return 1; @@ -2611,7 +2629,7 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) // debug( 1, L"%ls -> %ls %ls", arg_cpy, subst, tmp.buff ); - err |= parser_test( subst, babble ); + err |= parser_test( subst, out, prefix ); free( subst ); free( arg_cpy ); @@ -2645,13 +2663,13 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) case BRACKET_BEGIN: { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, offset, COMPLETE_VAR_BRACKET_DESC ); - print_errors(); + print_errors( out, prefix); } break; } @@ -2659,12 +2677,12 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) case INTERNAL_SEPARATOR: { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, offset, COMPLETE_VAR_PARAN_DESC ); - print_errors(); + print_errors( out, prefix); } break; } @@ -2672,12 +2690,12 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) case 0: { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, offset, COMPLETE_VAR_NULL_DESC ); - print_errors(); + print_errors( out, prefix); } break; } @@ -2691,13 +2709,13 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) !wcsvarchr(n) ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, offset, COMPLETE_VAR_DESC, *(pos+1) ); - print_errors(); + print_errors( out, prefix); } } @@ -2719,7 +2737,7 @@ static int parser_test_argument( const wchar_t *arg, int babble, int offset ) } int parser_test_args(const wchar_t * buff, - int babble ) + string_buffer_t *out, const wchar_t *prefix ) { tokenizer tok; tokenizer *previous_tokenizer = current_tokenizer; @@ -2739,7 +2757,7 @@ int parser_test_args(const wchar_t * buff, case TOK_STRING: { - err |= parser_test_argument( tok_last( &tok ), babble, tok_get_pos( &tok ) ); + err |= parser_test_argument( tok_last( &tok ), out, prefix, tok_get_pos( &tok ) ); break; } @@ -2750,13 +2768,13 @@ int parser_test_args(const wchar_t * buff, case TOK_ERROR: { - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), TOK_ERR_MSG, tok_last(&tok) ); - print_errors(); + print_errors( out, prefix ); } err=1; do_loop=0; @@ -2765,13 +2783,13 @@ int parser_test_args(const wchar_t * buff, default: { - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), UNEXPECTED_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(&tok)) ); - print_errors(); + print_errors( out, prefix ); } err=1; do_loop=0; @@ -2791,7 +2809,8 @@ int parser_test_args(const wchar_t * buff, } int parser_test( const wchar_t * buff, - int babble ) + string_buffer_t *out, + const wchar_t *prefix) { tokenizer tok; /* @@ -2842,14 +2861,14 @@ int parser_test( const wchar_t * buff, EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES ) ) ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), ILLEGAL_CMD_ERR_MSG, cmd ); - print_errors(); + print_errors( out, prefix ); } } @@ -2865,13 +2884,13 @@ int parser_test( const wchar_t * buff, 0 ) ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), COND_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } @@ -2899,7 +2918,7 @@ int parser_test( const wchar_t * buff, tok_get_pos( &tok ), BLOCK_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } else { @@ -2934,13 +2953,13 @@ int parser_test( const wchar_t * buff, if( is_pipeline ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } @@ -2956,13 +2975,13 @@ int parser_test( const wchar_t * buff, if( is_pipeline ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } @@ -2978,13 +2997,13 @@ int parser_test( const wchar_t * buff, { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_CASE_ERR_MSG ); - print_errors(); + print_errors( out, prefix); } } } @@ -3010,12 +3029,12 @@ int parser_test( const wchar_t * buff, { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_LOOP_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } } @@ -3028,13 +3047,13 @@ int parser_test( const wchar_t * buff, if( !count || block_type[count-1]!=IF ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_ELSE_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } @@ -3046,18 +3065,18 @@ int parser_test( const wchar_t * buff, if( count < 0 ) { err = 1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_END_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } } else { - err |= parser_test_argument( tok_last( &tok ), babble, tok_get_pos( &tok ) ); + err |= parser_test_argument( tok_last( &tok ), out, prefix, tok_get_pos( &tok ) ); /* If possible, keep track of number of supplied arguments @@ -3082,14 +3101,14 @@ int parser_test( const wchar_t * buff, { err = 1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), BUILTIN_FOR_ERR_IN, L"for" ); - print_errors(); + print_errors( out, prefix ); } } } @@ -3107,12 +3126,12 @@ int parser_test( const wchar_t * buff, if( !had_cmd ) { err = 1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_REDIRECTION_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } break; @@ -3123,13 +3142,13 @@ int parser_test( const wchar_t * buff, if( needs_cmd && !had_cmd ) { err = 1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), CMD_ERR_MSG, tok_get_desc( tok_last_type(&tok))); - print_errors(); + print_errors( out, prefix ); } } needs_cmd=0; @@ -3144,7 +3163,7 @@ int parser_test( const wchar_t * buff, if( !had_cmd ) { err=1; - if( babble ) + if( out ) { if( tok_get_pos(&tok)>0 && buff[tok_get_pos(&tok)-1] == L'|' ) { @@ -3162,19 +3181,19 @@ int parser_test( const wchar_t * buff, tok_get_desc( tok_last_type(&tok))); } - print_errors(); + print_errors( out, prefix ); } } else if( forbid_pipeline ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } else @@ -3191,7 +3210,7 @@ int parser_test( const wchar_t * buff, if( !had_cmd ) { err = 1; - if( babble ) + if( out ) { if( tok_get_pos(&tok)>0 && buff[tok_get_pos(&tok)-1] == L'&' ) { @@ -3209,7 +3228,7 @@ int parser_test( const wchar_t * buff, tok_get_desc( tok_last_type(&tok))); } - print_errors(); + print_errors( out, prefix ); } } @@ -3223,7 +3242,7 @@ int parser_test( const wchar_t * buff, case TOK_ERROR: default: err = 1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), @@ -3231,7 +3250,7 @@ int parser_test( const wchar_t * buff, tok_last(&tok) ); - print_errors(); + print_errors( out, prefix ); //debug( 2, tok_last( &tok) ); } break; @@ -3241,23 +3260,23 @@ int parser_test( const wchar_t * buff, if( needs_cmd ) { err=1; - if( babble ) + if( out ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), COND_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } } - if( babble && count>0 ) + if( out && count>0 ) { error( SYNTAX_ERROR, block_pos[count-1], BLOCK_END_ERR_MSG ); - print_errors(); + print_errors( out, prefix ); } tok_destroy( &tok ); diff --git a/parser.h b/parser.h index 944e1d3f4..ff1481713 100644 --- a/parser.h +++ b/parser.h @@ -320,7 +320,7 @@ const wchar_t *parser_get_block_desc( int block ); contains errors, and the second bit is set if the string contains an unclosed block. */ -int parser_test( const wchar_t * buff, int babble ); +int parser_test( const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ); /** Test if the specified string can be parsed as an argument list, @@ -328,7 +328,7 @@ int parser_test( const wchar_t * buff, int babble ); string contains errors, and the second bit is set if the string contains an unclosed block. */ -int parser_test_args( const wchar_t * buff, int babble ); +int parser_test_args( const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ); /** Returns the full path of the specified directory. If the \c in is a diff --git a/reader.c b/reader.c index 181786a18..7df9eba17 100644 --- a/reader.c +++ b/reader.c @@ -2099,10 +2099,15 @@ void reader_run_command( wchar_t *cmd ) static int shell_test( wchar_t *b ) { - if( parser_test( b, 0 ) ) + if( parser_test( b, 0, 0 ) ) { + string_buffer_t sb; + sb_init( &sb ); + writech( L'\n' ); - parser_test( b, 1 ); + parser_test( b, &sb, L"fish" ); + fwprintf( stderr, L"%ls", sb.buff ); + sb_destroy( &sb ); return 1; } return 0; @@ -2944,18 +2949,21 @@ static int read_ni( int fd ) if( str ) { - if( !parser_test( str, 1 ) ) - { - eval( str, 0, TOP ); - } - else - { - /* - No error reporting - parser_test did that for us - */ - res = 1; - } - free( str ); + string_buffer_t sb; + sb_init( &sb ); + + if( !parser_test( str, &sb, L"fish" ) ) + { + eval( str, 0, TOP ); + } + else + { + fwprintf( stderr, L"%ls", sb.buff ); + res = 1; + } + sb_destroy( &sb ); + + free( str ); } else {