Mercurial > octave
changeset 20653:c16947991354
avoid fixed-size buffers in index exception code
* lo-array-gripes.h, lo-array-gripes.cc (index_exception::expression):
Use std::ostringstream instead of fixed size buffer.
(gripe_invalid_index): Likewise.
(out_of_range::details): Likewise.
(index_exception::index_exception): Set default dim value to -1.
* ov-complex.h, ov-complex.cc (gripe_complex_index): Now static.
Pass arg by const reference instead of value. Use std::ostringstream
instead of fixed size buffer.
(octave_complex::index_vector): Move definition out of header file.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 22 Oct 2015 12:48:49 -0400 |
parents | 7a8096f8df5d |
children | b4ceb06009e0 |
files | libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-complex.h liboctave/util/lo-array-gripes.cc liboctave/util/lo-array-gripes.h |
diffstat | 4 files changed, 109 insertions(+), 135 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-complex.cc Wed Oct 21 23:43:46 2015 -0400 +++ b/libinterp/octave-value/ov-complex.cc Thu Oct 22 12:48:49 2015 -0400 @@ -25,6 +25,7 @@ #endif #include <iostream> +#include <sstream> #include "lo-ieee.h" #include "lo-specfun.h" @@ -55,6 +56,39 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex, "complex scalar", "double"); +// Complain if a complex value is used as a subscript. + +class complex_index_exception : public index_exception +{ +public: + + complex_index_exception (const std::string& value) + : index_exception (value) { } + + ~complex_index_exception (void) { } + + std::string details (void) const + { + return "subscripts must be real (forgot to initialize i or j?)"; + } + + // ID of error to throw. + const char *err_id (void) const + { + return error_id_invalid_index; + } +}; + +static void +gripe_complex_index (const Complex& idx) +{ + std::ostringstream buf; + buf << std::real (idx) << std::showpos << std::imag (idx) << "i"; + complex_index_exception e (buf.str ()); + + throw e; +} + static octave_base_value * default_numeric_demotion_function (const octave_base_value& a) { @@ -102,6 +136,14 @@ return tmp.do_index_op (idx, resize_ok); } +idx_vector +octave_complex::index_vector (bool) const +{ + gripe_complex_index (scalar); + + return idx_vector (); +} + double octave_complex::double_value (bool force_conversion) const { @@ -481,40 +523,3 @@ return octave_base_value::map (umap); } } - -class complex_index_exception : public index_exception -{ -public: - - complex_index_exception (const std::string& value) - : index_exception (value) { } - - ~complex_index_exception (void) { } - - std::string details (void) const - { - return "subscripts must be real (forgot to initialize i or j?)"; - } - - // ID of error to throw. - const char *err_id (void) const - { - return error_id_invalid_index; - } -}; - -// Complain if a complex value is used as a subscript - -void -gripe_complex_index (Complex idx) -{ - // FIXME: don't use a fixed size buffer! - - char buf [100]; - - sprintf (buf, "%g%+gi", std::real(idx), std::imag(idx)); - - complex_index_exception e (buf); - - throw e; -}
--- a/libinterp/octave-value/ov-complex.h Wed Oct 21 23:43:46 2015 -0400 +++ b/libinterp/octave-value/ov-complex.h Thu Oct 22 12:48:49 2015 -0400 @@ -43,9 +43,6 @@ class tree_walker; -extern void OCTAVE_API -gripe_complex_index (Complex idx); - // Complex scalar values. class @@ -81,12 +78,8 @@ octave_value do_index_op (const octave_value_list& idx, bool resize_ok = false); - // Use this to give a more specific error message - idx_vector index_vector (bool /* require_integers */ = false) const - { - gripe_complex_index (scalar); - return idx_vector (); - } + // Use this to give a more specific error message. + idx_vector index_vector (bool /* require_integers */ = false) const; octave_value any (int = 0) const {
--- a/liboctave/util/lo-array-gripes.cc Wed Oct 21 23:43:46 2015 -0400 +++ b/liboctave/util/lo-array-gripes.cc Thu Oct 22 12:48:49 2015 -0400 @@ -25,7 +25,7 @@ #include <config.h> #endif -#include <cstring> +#include <sstream> #include "lo-array-gripes.h" #include "lo-error.h" @@ -122,71 +122,45 @@ std::string index_exception::expression (void) const { - // FIXME: don't use a fixed size buffer! - const int buf_len = 300; - - char output [buf_len]; - char pre [buf_len]; - char post [buf_len]; + std::ostringstream buf; - // dim == 0 if position not yet given, or - // <static_cast unsigned int>(-1) if explicitly shown to be unknown - // both are caught by this condition + if (var.empty () || var == "<unknown>") + buf << "index "; + else + buf << var; - if (static_cast <unsigned int> (dim-1) > 100000) - { - // No parentheses are given if the dimension is not known. - pre[0] = post[0] = '\0'; - } - else + bool show_parens = dim > 0; + + if (show_parens) { if (dim < 5) { - pre[0] = '('; - octave_idx_type i; + buf << "("; - for (i = 1; i < dim; i++) - { - pre[2*i-1] = '_'; - pre[2*i] = ','; - } - - pre[2*i-1] = '\0'; // i == min (1, dim) + for (octave_idx_type i = 1; i < dim; i++) + buf << "_,"; } else - { - sprintf (pre, "(...[x%d]...", dim-1); - } + buf << "(...[x" << dim - 1 << "]..."; + } - if (static_cast <unsigned int> (nd-dim) < 5) + buf << idx (); + + if (show_parens) + { + if (nd - dim < 5) { - for (octave_idx_type i = 0; i < nd-dim; i++) - { - post[2*i] = ','; - post[2*i+1] = '_'; - } + for (octave_idx_type i = 0; i < nd - dim; i++) + buf << ",_"; if (nd >= dim) - { - post[2*(nd-dim)] = ')'; - post[2*(nd-dim)+1] = '\0'; - } + buf << ")"; } else - sprintf (post, "...[x%d]...)", nd-dim); + buf << "...[x" << nd - dim << "]...)"; } - const char *v; - - if (var[0] == '\0' || var == "<unknown>") - v = "index "; - else - v = var.c_str (); - - std::string tmp_idx = idx (); - snprintf (output, buf_len, "%s%s%s%s", v, pre, tmp_idx.c_str (), post); - - return output; + return buf.str (); } class invalid_index : public index_exception @@ -229,23 +203,18 @@ gripe_invalid_index (octave_idx_type n, octave_idx_type nd, octave_idx_type dim, const std::string& var) { - // Note: log10 (2^63) = 19 digits. - char buf[64]; - - sprintf (buf, "%d", n+1); - - gripe_invalid_index (buf, nd, dim, var); + std::ostringstream buf; + buf << n + 1; + gripe_invalid_index (buf.str (), nd, dim, var); } void gripe_invalid_index (double n, octave_idx_type nd, octave_idx_type dim, const std::string& var) { - char buf[64]; - - sprintf (buf, "%g", n+1); - - gripe_invalid_index (buf, nd, dim, var); + std::ostringstream buf; + buf << n + 1; + gripe_invalid_index (buf.str (), nd, dim, var); } @@ -275,9 +244,9 @@ } else { - char buf[64]; - sprintf (buf, "%d", extent); - expl = "out of bound " + std::string (buf); + std::ostringstream buf; + buf << extent; + expl = "out of bound " + buf.str (); } return expl; @@ -295,9 +264,11 @@ private: - dim_vector size; // dimension of object being accessed + // Dimension of object being accessed. + dim_vector size; - octave_idx_type extent; // length of dimension being accessed + // Length of dimension being accessed. + octave_idx_type extent; }; // Complain of an index that is out of range, but we don't know matrix size @@ -305,14 +276,15 @@ gripe_index_out_of_range (int nd, int dim, octave_idx_type idx, octave_idx_type ext) { - char buf[64]; - sprintf (buf, "%d", idx); - out_of_range e (buf, nd, dim); + std::ostringstream buf; + buf << idx; + out_of_range e (buf.str (), nd, dim); - e.set_extent (ext); - dim_vector d (1,1,1,1,1,1,1); // make explain give extent not size - e.set_size (d); - throw e; + e.set_extent (ext); + // ??? Make details method give extent not size. + e.set_size (dim_vector (1, 1, 1, 1, 1, 1,1)); + + throw e; } // Complain of an index that is out of range @@ -320,13 +292,14 @@ gripe_index_out_of_range (int nd, int dim, octave_idx_type idx, octave_idx_type ext, const dim_vector& d) { - char buf[64]; - sprintf (buf, "%d", idx); - out_of_range e (buf, nd, dim); + std::ostringstream buf; + buf << idx; + out_of_range e (buf.str (), nd, dim); - e.set_extent (ext); - e.set_size (d); - throw e; + e.set_extent (ext); + e.set_size (d); + + throw e; } void
--- a/liboctave/util/lo-array-gripes.h Wed Oct 21 23:43:46 2015 -0400 +++ b/liboctave/util/lo-array-gripes.h Thu Oct 22 12:48:49 2015 -0400 @@ -37,9 +37,9 @@ { public: - index_exception (const std::string& index_in, octave_idx_type nd_in = 0, - octave_idx_type dim_in = 0, const char *var_in = "") - : index (index_in), nd (nd_in), dim (dim_in), var (var_in) + 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) { } ~index_exception (void) { } @@ -57,23 +57,26 @@ virtual std::string message (void) const; // Position of error: dimension in error, and number of dimensions. - void set_pos (octave_idx_type nd_in, octave_idx_type dim_in) + void set_pos (octave_idx_type nd_arg, octave_idx_type dim_arg) { - nd = nd_in; - dim = dim_in; + nd = nd_arg; + dim = dim_arg; } - void set_pos_if_unset (octave_idx_type nd_in, octave_idx_type dim_in) + void set_pos_if_unset (octave_idx_type nd_arg, octave_idx_type dim_arg) { if (nd == 0) { - nd = nd_in; - dim = dim_in; + nd = nd_arg; + dim = dim_arg; } } // Name of variable being indexed. eye(2)(1,1) gives "<unknown>". - void set_var (const std::string& var_in = std::string ()) { var = var_in; } + void set_var (const std::string& var_arg = std::string ()) + { + var = var_arg; + } private: