diff --git a/libinterp/octave-value/ov-cell.cc b/libinterp/octave-value/ov-cell.cc --- a/libinterp/octave-value/ov-cell.cc +++ b/libinterp/octave-value/ov-cell.cc @@ -143,14 +143,23 @@ octave_cell::subsref (const std::string& case '{': { - octave_value tmp = do_index_op (idx.front ()); - - Cell tcell = tmp.cell_value (); + try + { + octave_value tmp = do_index_op (idx.front ()); - if (tcell.numel () == 1) - retval(0) = tcell(0,0); - else - retval = octave_value (octave_value_list (tcell), true); + Cell tcell = tmp.cell_value (); + + if (tcell.numel () == 1) + retval(0) = tcell(0,0); + else + retval = octave_value (octave_value_list (tcell), true); + } + catch (octave::index_exception& e) + { + // Rethrow to allow more info to be reported later. + e.set_type ('{'); + throw; + } } break; @@ -192,14 +201,23 @@ octave_cell::subsref (const std::string& case '{': { - octave_value tmp = do_index_op (idx.front (), auto_add); - - const Cell tcell = tmp.cell_value (); + try + { + octave_value tmp = do_index_op (idx.front (), auto_add); - if (tcell.numel () == 1) - retval = tcell(0,0); - else - retval = octave_value (octave_value_list (tcell), true); + const Cell tcell = tmp.cell_value (); + + if (tcell.numel () == 1) + retval = tcell(0,0); + else + retval = octave_value (octave_value_list (tcell), true); + } + catch (octave::index_exception& e) + { + // Rethrow to allow more info to be reported later. + e.set_type ('{'); + throw; + } } break; @@ -277,31 +295,40 @@ octave_cell::subsasgn (const std::string case '{': { - matrix.make_unique (); - Cell tmpc = matrix.index (idx.front (), true); - - std::list next_idx (idx); - - next_idx.erase (next_idx.begin ()); - - std::string next_type = type.substr (1); - - if (tmpc.numel () != 1) - err_indexed_cs_list (); + try + { + matrix.make_unique (); + Cell tmpc = matrix.index (idx.front (), true); - octave_value tmp = tmpc(0); - tmpc = Cell (); + std::list next_idx (idx); - if (! tmp.is_defined () || tmp.is_zero_by_zero ()) + next_idx.erase (next_idx.begin ()); + + std::string next_type = type.substr (1); + + if (tmpc.numel () != 1) + err_indexed_cs_list (); + + octave_value tmp = tmpc(0); + tmpc = Cell (); + + if (! tmp.is_defined () || tmp.is_zero_by_zero ()) + { + tmp = octave_value::empty_conv (type.substr (1), rhs); + tmp.make_unique (); // probably a no-op. + } + else + // optimization: ignore copy still stored inside array. + tmp.make_unique (1); + + t_rhs = tmp.subsasgn (next_type, next_idx, rhs); + } + catch (octave::index_exception& e) { - tmp = octave_value::empty_conv (type.substr (1), rhs); - tmp.make_unique (); // probably a no-op. + // Rethrow to allow more info to be reported later. + e.set_type (type[0]); + throw; } - else - // optimization: ignore copy still stored inside array. - tmp.make_unique (1); - - t_rhs = tmp.subsasgn (next_type, next_idx, rhs); } break; @@ -342,33 +369,42 @@ octave_cell::subsasgn (const std::string case '{': { - octave_value_list idxf = idx.front (); - - if (t_rhs.is_cs_list ()) + try { - Cell tmp_cell = Cell (t_rhs.list_value ()); - - // Inquire the proper shape of the RHS. - - dim_vector didx = dims ().redim (idxf.length ()); - for (octave_idx_type k = 0; k < idxf.length (); k++) - if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel (); + octave_value_list idxf = idx.front (); - if (didx.numel () == tmp_cell.numel ()) - tmp_cell = tmp_cell.reshape (didx); + if (t_rhs.is_cs_list ()) + { + Cell tmp_cell = Cell (t_rhs.list_value ()); - octave_base_matrix::assign (idxf, tmp_cell); + // Inquire the proper shape of the RHS. + + dim_vector didx = dims ().redim (idxf.length ()); + for (octave_idx_type k = 0; k < idxf.length (); k++) + if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel (); + + if (didx.numel () == tmp_cell.numel ()) + tmp_cell = tmp_cell.reshape (didx); + + octave_base_matrix::assign (idxf, tmp_cell); + } + else if (idxf.all_scalars () + || do_index_op (idxf, true).numel () == 1) + // Regularize a null matrix if stored into a cell. + octave_base_matrix::assign (idxf, + Cell (t_rhs.storable_value ())); + else + err_nonbraced_cs_list_assignment (); + + count++; + retval = octave_value (this); } - else if (idxf.all_scalars () - || do_index_op (idxf, true).numel () == 1) - // Regularize a null matrix if stored into a cell. - octave_base_matrix::assign (idxf, - Cell (t_rhs.storable_value ())); - else - err_nonbraced_cs_list_assignment (); - - count++; - retval = octave_value (this); + catch (octave::index_exception& e) + { + // Rethrow to allow more info to be reported later. + e.set_type (type[0]); + throw; + } } break; diff --git a/liboctave/util/lo-array-errwarn.cc b/liboctave/util/lo-array-errwarn.cc --- a/liboctave/util/lo-array-errwarn.cc +++ b/liboctave/util/lo-array-errwarn.cc @@ -136,13 +136,13 @@ namespace octave { if (dim < 5) { - buf << "("; + buf << open_delim (); for (octave_idx_type i = 1; i < dim; i++) buf << "_,"; } else - buf << "(...[x" << dim - 1 << "]..."; + buf << open_delim () << "...[x" << dim - 1 << "]..."; } buf << idx (); @@ -155,15 +155,25 @@ namespace octave buf << ",_"; if (nd >= dim) - buf << ")"; + buf << close_delim (); } else - buf << "...[x" << nd - dim << "]...)"; + buf << "...[x" << nd - dim << "]..." << close_delim (); } return buf.str (); } + char index_exception::open_delim (void) const + { + return type == '(' ? '(' : '{'; + } + + char index_exception::close_delim (void) const + { + return type == '(' ? ')' : '}'; + } + class invalid_index : public index_exception { public: diff --git a/liboctave/util/lo-array-errwarn.h b/liboctave/util/lo-array-errwarn.h --- a/liboctave/util/lo-array-errwarn.h +++ b/liboctave/util/lo-array-errwarn.h @@ -43,8 +43,10 @@ namespace octave public: index_exception (const std::string& index_arg, octave_idx_type nd_arg = 0, - octave_idx_type dim_arg = -1, const char *var_arg = "") - : index (index_arg), nd (nd_arg), dim (dim_arg), var (var_arg) + octave_idx_type dim_arg = -1, const char *var_arg = "", + char type_arg = '(') + : index (index_arg), var (var_arg), nd (nd_arg), dim (dim_arg), + type (type_arg) { } ~index_exception (void) = default; @@ -83,15 +85,28 @@ namespace octave var = var_arg; } + void set_type (char type_arg) + { + type = type_arg; + } + + protected: + + // Show what's wrong, e.g., A(-1,_), A(0+1i). + std::string expression (void) const; + private: + char open_delim (void) const; + char close_delim (void) const; + // Value of invalid index. std::string index; protected: - // Show what's wrong, e.g., A(-1,_), A(0+1i). - std::string expression (void) const; + // Name of variable being indexed. + std::string var; // Number of dimensions of indexed object. octave_idx_type nd; @@ -99,9 +114,8 @@ namespace octave // Dimension number in which invalid index occurred. octave_idx_type dim; - // Name of variable being indexed. - std::string var; - + // Type of index '(' or '{'. + char type; }; OCTAVE_NORETURN OCTAVE_API extern void