diff --git a/expand.c b/expand.c index a83dcfa37..84bee780d 100644 --- a/expand.c +++ b/expand.c @@ -46,6 +46,26 @@ parameter expansion. #include "parse_util.h" #include "halloc_util.h" +/** + Error issued on invalid variable name +*/ +#define COMPLETE_VAR_DESC _( L"The '$' character begins a variable name. The character '%lc', which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.") + +/** + Error issued on invalid variable name +*/ +#define COMPLETE_VAR_NULL_DESC _( L"The '$' begins a variable name. It was given at the end of an argument. Variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.") + +/** + Error issued on invalid variable name +*/ +#define COMPLETE_VAR_BRACKET_DESC _( L"Did you mean {$VARIABLE}? The '$' character begins a variable name. A bracket, which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'." ) + +/** + Error issued on invalid variable name +*/ +#define COMPLETE_VAR_PARAN_DESC _( L"Did you mean (COMMAND)? In fish, the '$' character is only used for accessing variables. To learn more about command substitution in fish, type 'help expand-command-substitution'.") + /** Description for child process */ @@ -649,6 +669,49 @@ static int expand_pid( wchar_t *in, return 1; } + +void expand_variable_error( const wchar_t *token, int token_pos, int error_pos ) +{ + int stop_pos = token_pos+1; + + switch( token[stop_pos] ) + { + case BRACKET_BEGIN: + { + error( SYNTAX_ERROR, + error_pos, + COMPLETE_VAR_BRACKET_DESC ); + break; + } + + case INTERNAL_SEPARATOR: + { + error( SYNTAX_ERROR, + error_pos, + COMPLETE_VAR_PARAN_DESC ); + break; + } + + case 0: + { + error( SYNTAX_ERROR, + error_pos, + COMPLETE_VAR_NULL_DESC ); + break; + } + + default: + { + error( SYNTAX_ERROR, + error_pos, + COMPLETE_VAR_DESC, + token[stop_pos] ); + break; + } + } +} + + /** Expand all environment variables in the string *ptr. @@ -735,43 +798,8 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) if( var_len == 0 ) { - switch( in[stop_pos] ) - { - case BRACKET_BEGIN: - { - error( SYNTAX_ERROR, - -1, - COMPLETE_VAR_BRACKET_DESC ); - break; - } - - case INTERNAL_SEPARATOR: - { - error( SYNTAX_ERROR, - -1, - COMPLETE_VAR_PARAN_DESC ); - break; - } - - case 0: - { - error( SYNTAX_ERROR, - -1, - COMPLETE_VAR_NULL_DESC ); - break; - } - - default: - { - error( SYNTAX_ERROR, - -1, - COMPLETE_VAR_DESC, - in[stop_pos] ); - break; - } - } - - + expand_variable_error( in, stop_pos-1, -1 ); + is_ok = 0; break; } diff --git a/expand.h b/expand.h index b3d79ce81..820f5f804 100644 --- a/expand.h +++ b/expand.h @@ -112,26 +112,6 @@ enum /** String containing the character for separating two array elements */ #define ARRAY_SEP_STR L"\x1e" -/** - Error issued on invalid variable name -*/ -#define COMPLETE_VAR_DESC _( L"The '$' character begins a variable name. The character '%lc', which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.") - -/** - Error issued on invalid variable name -*/ -#define COMPLETE_VAR_NULL_DESC _( L"The '$' begins a variable name. It was given at the end of an argument. Variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'.") - -/** - Error issued on invalid variable name -*/ -#define COMPLETE_VAR_BRACKET_DESC _( L"Did you mean {$VARIABLE}? The '$' character begins a variable name. A bracket, which directly followed a '$', is not allowed as a part of a variable name, and variable names may not be zero characters long. To learn more about variable expansion in fish, type 'help expand-variable'." ) - -/** - Error issued on invalid variable name -*/ -#define COMPLETE_VAR_PARAN_DESC _( L"Did you mean (COMMAND)? In fish, the '$' character is only used for accessing variables. To learn more about command substitution in fish, type 'help expand-command-substitution'.") - /** Error issued on array out of bounds */ @@ -207,4 +187,17 @@ wchar_t *expand_tilde(wchar_t *in); */ int expand_is_clean( const wchar_t *in ); +/** + Perform error reporting for a syntax error related to the variable + expansion beginning at the specified character of the specified + token. This function will call the error function with an + explanatory string about what is wrong with the specified token. + + \param token The token containing the error + \param token_pos The position where the expansion begins + \param error_pos The position on the line to report to the error function. +*/ +void expand_variable_error( const wchar_t *token, int token_pos, int error_pos ); + + #endif diff --git a/parser.c b/parser.c index b84b22db6..403b2c9fa 100644 --- a/parser.c +++ b/parser.c @@ -2850,70 +2850,18 @@ static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const case VARIABLE_EXPAND: case VARIABLE_EXPAND_SINGLE: { - switch( *(pos+1)) + wchar_t n = *(pos+1); + + if( n != VARIABLE_EXPAND && + n != VARIABLE_EXPAND_SINGLE && + !wcsvarchr(n) ) { - case BRACKET_BEGIN: + err=1; + if( out ) { - err=1; - if( out ) - { - error( SYNTAX_ERROR, - offset, - COMPLETE_VAR_BRACKET_DESC ); - - print_errors( out, prefix); - } - break; + expand_variable_error( unesc, pos-unesc, offset ); + print_errors( out, prefix); } - - case INTERNAL_SEPARATOR: - { - err=1; - if( out ) - { - error( SYNTAX_ERROR, - offset, - COMPLETE_VAR_PARAN_DESC ); - print_errors( out, prefix); - } - break; - } - - case 0: - { - err=1; - if( out ) - { - error( SYNTAX_ERROR, - offset, - COMPLETE_VAR_NULL_DESC ); - print_errors( out, prefix); - } - break; - } - - default: - { - wchar_t n = *(pos+1); - - if( n != VARIABLE_EXPAND && - n != VARIABLE_EXPAND_SINGLE && - !wcsvarchr(n) ) - { - err=1; - if( out ) - { - error( SYNTAX_ERROR, - offset, - COMPLETE_VAR_DESC, - *(pos+1) ); - print_errors( out, prefix); - } - } - - break; - } - } break; @@ -3053,7 +3001,7 @@ int parser_test( const wchar_t * buff, int mark = tok_get_pos( &tok ); had_cmd = 1; arg_count=0; - + if( !(cmd = expand_one( context, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES ) ) )