diff --git a/builtin.c b/builtin.c index a9de36059..eac987b95 100644 --- a/builtin.c +++ b/builtin.c @@ -1321,6 +1321,31 @@ static int builtin_read( wchar_t **argv ) builtin_print_help( argv[0], sb_err ); return 1; } + + /* + Verify all variable names + */ + for( i=woptind; i al_get_count( &l ) ) { - error( SYNTAX_ERROR, L"Array index out of bounds", -1 ); + error( SYNTAX_ERROR, + -1, + L"Array index out of bounds" ); is_ok=0; al_truncate( &idx, j ); break; @@ -877,8 +879,7 @@ static int expand_variables( wchar_t *in, array_list_t *out ) if( !(new_in = malloc( sizeof(wchar_t)*new_len ))) { - error( OOM, L"Out of memory", -1 ); - is_ok = 0; + die_mem(); } else { @@ -1047,7 +1048,9 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out ) if( syntax_error ) { - error( SYNTAX_ERROR, L"Mismatched brackets", -1 ); + error( SYNTAX_ERROR, + -1, + L"Mismatched brackets" ); return 0; } @@ -1193,7 +1196,9 @@ static int expand_subshell( wchar_t *in, array_list_t *out ) 0 ) ) { case -1: - error( SYNTAX_ERROR, L"Mismatched parans", -1 ); + error( SYNTAX_ERROR, + -1, + L"Mismatched parans" ); return 0; case 0: al_push( out, in ); @@ -1272,7 +1277,7 @@ wchar_t *expand_unescape( const wchar_t * in, int escape_special ) { wchar_t *res = unescape( in, escape_special ); if( !res ) - error( SYNTAX_ERROR, L"Unexpected end of string", -1 ); + error( SYNTAX_ERROR, -1, L"Unexpected end of string" ); return res; } @@ -1441,7 +1446,7 @@ int expand_string( wchar_t *str, if( (pos == str) || ( *(pos-1) != L'\\' ) ) { - error( SUBSHELL_ERROR, L"Subshells not allowed", -1 ); + error( SUBSHELL_ERROR, -1, L"Subshells not allowed" ); free( str ); al_destroy( &list1 ); al_destroy( &list2 ); diff --git a/parser.c b/parser.c index ccb0a9968..7748c8657 100644 --- a/parser.c +++ b/parser.c @@ -66,7 +66,7 @@ The fish parser. Contains functions for parsing code. Error message for tokenizer error. The tokenizer message is appended to this message. */ -#define TOK_ERR_MSG L"Tokenizer error" +#define TOK_ERR_MSG L"Tokenizer error: %ls" /** Error message for short circut command error. @@ -101,7 +101,12 @@ The fish parser. Contains functions for parsing code. /** Error message for wildcards with no matches */ -#define WILDCARD_ERR_MSG L"Warning: No match for wildcard " +#define WILDCARD_ERR_MSG L"Warning: No match for wildcard %ls" + +/** + Error message for Posix-style assignment +*/ +#define COMMAND_ASSIGN_ERR_MSG L"Unknown command %ls. Did you mean 'set VARIABLE VALUE'? For information on setting variable values, see the manual section on the set command by typing 'help set'." /** Last error code */ int error_code; @@ -564,21 +569,17 @@ void parser_allow_function() free( (void *) al_pop( &forbidden_function ) ); } -void error( int ec, const wchar_t *str, int p ) +void error( int ec, int p, const wchar_t *str, ... ) { - error_code = ec; - wcsncpy( err_str, str, 256 ); - err_pos = p; -} + va_list va; + + error_code = ec; + err_pos = p; + + va_start( va, str ); + vswprintf( err_str, 256, str, va ); + va_end( va ); -/** - Wrapper for the error function, which sets the error string to "ec 'ea'". -*/ -static void error_arg( int ec, const wchar_t *es, const wchar_t *ea, int p ) -{ - wchar_t *msg = wcsdupcat2( es, L" \'", ea, L"\'", 0 ); - error( ec, msg, p ); - free(msg); } wchar_t *get_filename( const wchar_t *cmd ) @@ -824,20 +825,21 @@ int eval_args( const wchar_t *line, array_list_t *args ) case TOK_ERROR: { - error_arg( SYNTAX_ERROR, - TOK_ERR_MSG, - tok_last(&tok), - tok_get_pos( &tok ) ); - + error( SYNTAX_ERROR, + tok_get_pos( &tok ), + TOK_ERR_MSG, + tok_last(&tok) ); + do_loop=0; break; } default: - error_arg( SYNTAX_ERROR, - L"Unexpected token of type", - tok_get_desc( tok_last_type(&tok)), - tok_get_pos( &tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( &tok ), + L"Unexpected token of type %ls", + tok_get_desc( tok_last_type(&tok)) ); + do_loop=0; break; @@ -1000,8 +1002,8 @@ static void parse_job_main_loop( process_t *p, if( (p->type == INTERNAL_EXEC) ) { error( SYNTAX_ERROR, - EXEC_ERR_MSG, - tok_get_pos( tok ) ); + tok_get_pos( tok ), + EXEC_ERR_MSG ); return; } p->pipe_fd = wcstol( tok_last( tok ), 0, 10 ); @@ -1079,10 +1081,11 @@ static void parse_job_main_loop( process_t *p, err_pos=tok_get_pos( tok ); if( error_code == 0 ) { - error_arg( SYNTAX_ERROR, - L"Could not expand string", - tok_last(tok), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Could not expand string", + tok_last(tok) ); + } break; } @@ -1155,27 +1158,27 @@ static void parse_job_main_loop( process_t *p, target = expand_one( wcsdup( tok_last( tok ) ), 0); if( target == 0 && error_code == 0 ) { - error_arg( SYNTAX_ERROR, - L"Could not expand string", - tok_last( tok ), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Could not expand string %ls", + tok_last( tok ) ); } } break; default: - error_arg( SYNTAX_ERROR, - L"Expected redirection, got token of type", - tok_get_desc( tok_last_type(tok)), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Expected redirection, got token of type %ls", + tok_get_desc( tok_last_type(tok)) ); } if( target == 0 || wcslen( target )==0 ) { if( error_code == 0 ) error( SYNTAX_ERROR, - L"Invalid IO redirection", - tok_get_pos( tok ) ); + tok_get_pos( tok ), + L"Invalid IO redirection" ); tok_next(tok); } else @@ -1216,11 +1219,12 @@ static void parse_job_main_loop( process_t *p, if( ( new_io->param1.old_fd < 0 ) || ( new_io->param1.old_fd > 10 ) ) { - error_arg( SYNTAX_ERROR, - L"Requested redirection to something " - L"that is not a file descriptor", - target, - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Requested redirection to something " + L"that is not a file descriptor %ls", + target ); + tok_next(tok); } free(target); @@ -1236,19 +1240,20 @@ static void parse_job_main_loop( process_t *p, case TOK_ERROR: { - error_arg( SYNTAX_ERROR, - TOK_ERR_MSG, - tok_last(tok), - tok_get_pos( tok ) ); - + error( SYNTAX_ERROR, + tok_get_pos( tok ), + TOK_ERR_MSG, + tok_last(tok) ); + return; } default: - error_arg( SYNTAX_ERROR, - L"Unexpected token of type", - tok_get_desc( tok_last_type(tok)), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Unexpected token of type %ls", + tok_get_desc( tok_last_type(tok)) ); + tok_next(tok); break; } @@ -1263,10 +1268,11 @@ static void parse_job_main_loop( process_t *p, { if( unmatched_wildcard && !matched_wildcard ) { - error_arg( WILDCARD_ERROR, - WILDCARD_ERR_MSG, - unmatched, - unmatched_pos ); + error( WILDCARD_ERROR, + unmatched_pos, + WILDCARD_ERR_MSG, + unmatched ); + } } free( unmatched ); @@ -1311,10 +1317,11 @@ static int parse_job( process_t *p, EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES); if( nxt == 0 ) { - error_arg( SYNTAX_ERROR, - L"Illegal command name ", - tok_last( tok ), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Illegal command name %ls", + tok_last( tok ) ); + al_destroy( &args ); return 0; } @@ -1323,21 +1330,22 @@ static int parse_job( process_t *p, case TOK_ERROR: { - error_arg( SYNTAX_ERROR, - TOK_ERR_MSG, - tok_last(tok), - tok_get_pos( tok ) ); - + error( SYNTAX_ERROR, + tok_get_pos( tok ), + TOK_ERR_MSG, + tok_last(tok) ); + al_destroy( &args ); return 0; } default: { - error_arg( SYNTAX_ERROR, - L"Expected a command name, got token of type ", - tok_get_desc( tok_last_type(tok)), - tok_get_pos( tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Expected a command name, got token of type %ls", + tok_get_desc( tok_last_type(tok) ) ); + al_destroy( &args ); return 0; } @@ -1421,8 +1429,8 @@ static int parse_job( process_t *p, if( p != j->first_process ) { error( SYNTAX_ERROR, - EXEC_ERR_MSG, - tok_get_pos( tok ) ); + tok_get_pos( tok ), + EXEC_ERR_MSG ); al_destroy( &args ); free(nxt); return 0; @@ -1506,8 +1514,8 @@ static int parse_job( process_t *p, if( al_get_count( &forbidden_function ) > MAX_RECURSION_DEPTH ) { error( SYNTAX_ERROR, - RECURSION_ERR_MSG, - tok_get_pos( tok ) ); + tok_get_pos( tok ), + RECURSION_ERR_MSG ); } else { @@ -1577,10 +1585,23 @@ static int parse_job( process_t *p, } else { - error_arg( EVAL_ERROR, - L"Unknown command", - (wchar_t *)al_get( &args, 0 ), - tok_get_pos( tok ) ); + if( wcschr( (wchar_t *)al_get( &args, 0 ), L'=' ) ) + { + error( EVAL_ERROR, + tok_get_pos( tok ), + COMMAND_ASSIGN_ERR_MSG, + (wchar_t *)al_get( &args, 0 ) ); + + + } + else + { + error( EVAL_ERROR, + tok_get_pos( tok ), + L"Unknown command %ls", + (wchar_t *)al_get( &args, 0 ) ); + + } } } } @@ -1597,8 +1618,8 @@ static int parse_job( process_t *p, if( !end ) { error( SYNTAX_ERROR, - L"Could not find end of block" , - tok_get_pos( tok ) ); + tok_get_pos( tok ), + L"Could not find end of block" ); } if( !make_sub_block ) @@ -1622,8 +1643,8 @@ static int parse_job( process_t *p, default: { error( SYNTAX_ERROR, - BLOCK_END_ERR_MSG, - current_tokenizer_pos ); + current_tokenizer_pos, + BLOCK_END_ERR_MSG ); } } tok_destroy( &subtok ); @@ -1902,21 +1923,21 @@ static void eval_job( tokenizer *tok ) case TOK_ERROR: { - error_arg( SYNTAX_ERROR, - TOK_ERR_MSG, - tok_last(tok), - tok_get_pos( tok ) ); - + error( SYNTAX_ERROR, + tok_get_pos( tok ), + TOK_ERR_MSG, + tok_last(tok) ); + return; } default: { - error_arg( SYNTAX_ERROR, - L"Expected a command string, got token of type", - tok_get_desc( tok_last_type(tok)), - tok_get_pos( tok ) ); - + error( SYNTAX_ERROR, + tok_get_pos( tok ), + L"Expected a command string, got token of type %ls", + tok_get_desc( tok_last_type(tok)) ); + return; } } @@ -2098,8 +2119,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - COND_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + COND_ERR_MSG ); + print_errors(); } } @@ -2124,7 +2146,10 @@ int parser_test( wchar_t * buff, { if( count >= BLOCK_MAX_COUNT ) { - error( SYNTAX_ERROR, BLOCK_ERR_MSG, tok_get_pos( &tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( &tok ), + BLOCK_ERR_MSG ); + print_errors(); } else @@ -2180,8 +2205,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - EXEC_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + EXEC_ERR_MSG ); + print_errors(); } @@ -2202,8 +2228,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - EXEC_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + EXEC_ERR_MSG ); + print_errors(); } @@ -2226,8 +2253,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - L"'case' builtin not inside of switch block", - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + L"'case' builtin not inside of switch block" ); + print_errors(); } } @@ -2258,9 +2286,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - L"Loop control command while not inside of loop", - tok_get_pos( &tok ) ); - print_errors(); + tok_get_pos( &tok ), + L"Loop control command while not inside of loop" ); + print_errors(); } } } @@ -2276,9 +2304,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - L"'else' builtin not inside of if block", - tok_get_pos( &tok ) ); - print_errors(); + tok_get_pos( &tok ), + L"'else' builtin not inside of if block" ); + print_errors(); } } @@ -2293,8 +2321,8 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - L"'end' command outside of block", - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + L"'end' command outside of block" ); print_errors(); } } @@ -2313,8 +2341,8 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - L"Redirection error", - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + L"Redirection error" ); print_errors(); } } @@ -2329,9 +2357,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - CMD_ERR_MSG, - tok_get_pos( &tok ) ); - print_errors(); + tok_get_pos( &tok ), + CMD_ERR_MSG ); + print_errors(); } } needs_cmd=0; @@ -2349,8 +2377,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - EXEC_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + EXEC_ERR_MSG ); + print_errors(); } } @@ -2367,8 +2396,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - CMD_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + CMD_ERR_MSG ); + print_errors(); } } @@ -2385,10 +2415,12 @@ int parser_test( wchar_t * buff, err = 1; if( babble ) { - error_arg( SYNTAX_ERROR, - TOK_ERR_MSG, - tok_last(&tok), - tok_get_pos( &tok ) ); + error( SYNTAX_ERROR, + tok_get_pos( &tok ), + TOK_ERR_MSG, + tok_last(&tok) ); + + print_errors(); //debug( 2, tok_last( &tok) ); } @@ -2402,8 +2434,9 @@ int parser_test( wchar_t * buff, if( babble ) { error( SYNTAX_ERROR, - COND_ERR_MSG, - tok_get_pos( &tok ) ); + tok_get_pos( &tok ), + COND_ERR_MSG ); + print_errors(); } } @@ -2412,8 +2445,8 @@ int parser_test( wchar_t * buff, if( babble && count>0 ) { error( SYNTAX_ERROR, - END_ERR_MSG L"\n", - block_pos[count-1] ); + block_pos[count-1], + END_ERR_MSG ); print_errors(); } diff --git a/parser.h b/parser.h index fc4fbfe77..2a597a1e0 100644 --- a/parser.h +++ b/parser.h @@ -200,10 +200,11 @@ int eval_args( const wchar_t *line, Sets the current error \param ec The new error code - \param str The new error message \param p The character offset at which the error occured + \param str The printf-style error message filter */ -void error( int ec, const wchar_t *str, int p ); +void error( int ec, int p, const wchar_t *str, ... ); + /** Tests if the specified commands parameters should be interpreted as another command, which will be true if the command is either 'command', 'exec', 'if', 'while' or 'builtin'. diff --git a/wildcard.c b/wildcard.c index 75de72d0c..959519ec3 100644 --- a/wildcard.c +++ b/wildcard.c @@ -70,7 +70,7 @@ int wildcard_has( const wchar_t *str, int internal ) \param str String to be matched. \param wc The wildcard. - \param is_first Whether files beginning with dots should not be matched against wildcards. + \param is_first Whether files beginning with dots should not be matched against wildcards. \param wc_unescaped Whether the unescaped special character ANY_CHAR abd ANY_STRING should be used instead of '?' and '*' for wildcard matching */ @@ -358,7 +358,7 @@ int wildcard_expand( const wchar_t *wc, /* Description for completions */ string_buffer_t sb_desc; -// debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir ); + // debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir ); if( flags & ACCEPT_INCOMPLETE ) {