diff options
-rw-r--r-- | expand.cpp | 64 | ||||
-rw-r--r-- | tests/test8.err | 0 | ||||
-rw-r--r-- | tests/test8.in | 21 | ||||
-rw-r--r-- | tests/test8.out | 9 | ||||
-rw-r--r-- | tests/test8.status | 1 | ||||
-rw-r--r-- | tests/top.out | 1 |
6 files changed, 61 insertions, 35 deletions
@@ -727,7 +727,7 @@ void expand_variable_error( parser_t &parser, const wchar_t *token, int token_po /** Parse an array slicing specification */ -static int parse_slice( const wchar_t *in, wchar_t **end_ptr, std::vector<long> &idx, int size=-1 ) +static int parse_slice( const wchar_t *in, wchar_t **end_ptr, std::vector<long> &idx, int size ) { wchar_t *end; @@ -757,6 +757,7 @@ static int parse_slice( const wchar_t *in, wchar_t **end_ptr, std::vector<long> } // debug( 0, L"Push idx %d", tmp ); + long i1 = tmp>-1 ? tmp : size+tmp+1; pos = end-in; if ( in[pos]==L'.' && in[pos+1]==L'.' ){ pos+=2; @@ -767,23 +768,19 @@ static int parse_slice( const wchar_t *in, wchar_t **end_ptr, std::vector<long> } pos = end-in; - if ( size>-1 ) { - // debug( 0, L"Push range idx %d %d", tmp, tmp1 ); - long i1 = tmp>-1 ? tmp : size+tmp+1; - long i2 = tmp1>-1 ? tmp1 : size+tmp1+1; - // debug( 0, L"Push range idx %d %d", i1, i2 ); - short direction = i2<i1 ? -1 : 1 ; - for (long jjj = i1; jjj*direction <= i2*direction; jjj+=direction) { - // debug(0, L"Expand range [subst]: %i\n", jjj); - idx.push_back( jjj ); - } + // debug( 0, L"Push range %d %d", tmp, tmp1 ); + long i2 = tmp1>-1 ? tmp1 : size+tmp1+1; + // debug( 0, L"Push range idx %d %d", i1, i2 ); + short direction = i2<i1 ? -1 : 1 ; + for (long jjj = i1; jjj*direction <= i2*direction; jjj+=direction) { + // debug(0, L"Expand range [subst]: %i\n", jjj); + idx.push_back( jjj ); } continue; } // debug( 0, L"Push idx %d", tmp ); - idx.push_back(tmp); - // idx.push_back(tmp2); + idx.push_back( i1 ); } if( end_ptr ) @@ -875,25 +872,26 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std: int all_vars=1; wcstring_list_t var_item_list; - if( in[stop_pos] == L'[' ) - { - wchar_t *slice_end; - all_vars=0; - - if( parse_slice( in + stop_pos, &slice_end, var_idx_list ) ) - { - parser.error( SYNTAX_ERROR, - -1, - L"Invalid index value" ); - is_ok = 0; - } - stop_pos = (slice_end-in); - } - if( is_ok ) { tokenize_variable_array( var_val.c_str(), var_item_list ); + if( in[stop_pos] == L'[' ) + { + wchar_t *slice_end; + all_vars=0; + + if( parse_slice( in + stop_pos, &slice_end, var_idx_list, var_item_list.size() ) ) + { + parser.error( SYNTAX_ERROR, + -1, + L"Invalid index value" ); + is_ok = 0; + break; + } + stop_pos = (slice_end-in); + } + if( !all_vars ) { wcstring_list_t string_values(var_idx_list.size()); @@ -901,11 +899,6 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std: for( size_t j=0; j<var_idx_list.size(); j++) { long tmp = var_idx_list.at(j); - if( tmp < 0 ) - { - tmp = ((long)var_item_list.size())+tmp+1; - } - /* Check that we are within array bounds. If not, truncate the list to @@ -1224,10 +1217,11 @@ static int expand_cmdsubst( parser_t &parser, const wcstring &input, std::vector long idx = slice_idx.at(i); if( idx < 1 || (size_t)idx > sub_res.size() ) { - parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); + parser.error( SYNTAX_ERROR, + -1, + ARRAY_BOUNDS_ERR ); return 0; } - idx = idx-1; sub_res2.push_back(sub_res.at(idx)); diff --git a/tests/test8.err b/tests/test8.err new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/test8.err diff --git a/tests/test8.in b/tests/test8.in new file mode 100644 index 00000000..e03d9d05 --- /dev/null +++ b/tests/test8.in @@ -0,0 +1,21 @@ +# Test index ranges + +# Test variable expand +set test (seq 10) +echo $test[1..10] # normal range +echo $test[10..1] # inverted range +echo $test[2..5 8..6] # several ranges +echo $test[-1..-2] # range with negative limits +echo $test[-1..1] # range with mixed limits + +# Test variable set +set test1 $test +set test1[-1..1] $test # reverse variable +echo $echo $test1 +set test1[2..4 -2..-4] $test1[4..2 -4..-2] +echo $test1 + +# Test command substitution +echo (seq 5)[-1..1] +echo (seq 10)[3..5 -2..2] + diff --git a/tests/test8.out b/tests/test8.out new file mode 100644 index 00000000..e118e572 --- /dev/null +++ b/tests/test8.out @@ -0,0 +1,9 @@ +1 2 3 4 5 6 7 8 9 10 +10 9 8 7 6 5 4 3 2 1 +2 3 4 5 8 7 6 +10 9 +10 9 8 7 6 5 4 3 2 1 +10 9 8 7 6 5 4 3 2 1 +10 7 8 9 6 5 2 3 4 1 +5 4 3 2 1 +3 4 5 9 8 7 6 5 4 3 2 diff --git a/tests/test8.status b/tests/test8.status new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/tests/test8.status @@ -0,0 +1 @@ +0 diff --git a/tests/top.out b/tests/top.out index 5614a661..0c7b1103 100644 --- a/tests/top.out +++ b/tests/top.out @@ -6,3 +6,4 @@ File test4.in tested ok File test5.in tested ok File test6.in tested ok File test7.in tested ok +File test8.in tested ok |