# HG changeset patch # User John W. Eaton # Date 1388720677 18000 # Node ID 1b6db9303933d99a35d21e8914c02a82ccd21c5e # Parent 1461b9cfac4e8a9a58d810e25bdc07e6839ab013 allow toupper and tolower to handle numeric values (bug #33537) * ov-base-sparse.cc (octave_base_sparse::map): Special case for umap_xtolower and umap_xtoupper. * ov-float.cc (octave_float_scalar::map): Likewise. * ov-flt-re-mat.cc (octave_float_matrix::map): Likewise. * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::map, OCTAVE_VALUE_INT_SCALAR_T::map): Likewise. * ov-re-mat.cc (octave_matrix::map): Likewise. * ov-scalar.cc (octave_scalar::map): Likewise. * build-sparse-tests.sh, mappers.cc: Update tests. diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/corefcn/mappers.cc --- a/libinterp/corefcn/mappers.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/corefcn/mappers.cc Thu Jan 02 22:44:37 2014 -0500 @@ -2156,8 +2156,17 @@ %!assert (tolower ({"ABC", "DEF", {"GHI", {"JKL"}}}), {"abc", "def", {"ghi", {"jkl"}}}) %!assert (tolower (["ABC"; "DEF"]), ["abc"; "def"]) %!assert (tolower ({["ABC"; "DEF"]}), {["abc";"def"]}) -%!assert (tolower (68), "d") -%!assert (tolower ({[68, 68; 68, 68]}), {["dd";"dd"]}) +%!assert (tolower (68), 68) +%!assert (tolower ({[68, 68; 68, 68]}), {[68, 68; 68, 68]}) +%!test +%! classes = {@char, @double, @single, ... +%! @int8, @int16, @int32, @int64, ... +%! @uint8, @uint16, @uint32, @uint64}; +%! for i = 1:numel (classes) +%! cls = classes{i}; +%! assert (class (tolower (cls (97))), class (cls (97))); +%! assert (class (tolower (cls ([98, 99]))), class (cls ([98, 99]))); +%! endfor %!test %! a(3,3,3,3) = "D"; %! assert (tolower (a)(3,3,3,3), "d"); @@ -2207,8 +2216,17 @@ %!assert (toupper ({"abc", "def", {"ghi", {"jkl"}}}), {"ABC", "DEF", {"GHI", {"JKL"}}}) %!assert (toupper (["abc"; "def"]), ["ABC"; "DEF"]) %!assert (toupper ({["abc"; "def"]}), {["ABC";"DEF"]}) -%!assert (toupper (100), "D") -%!assert (toupper ({[100, 100; 100, 100]}), {["DD";"DD"]}) +%!assert (toupper (100), 100) +%!assert (toupper ({[100, 100; 100, 100]}), {[100, 100; 100, 100]}) +%!test +%! classes = {@char, @double, @single, ... +%! @int8, @int16, @int32, @int64, ... +%! @uint8, @uint16, @uint32, @uint64}; +%! for i = 1:numel (classes) +%! cls = classes{i}; +%! assert (class (toupper (cls (97))), class (cls (97))); +%! assert (class (toupper (cls ([98, 99]))), class (cls ([98, 99]))); +%! endfor %!test %! a(3,3,3,3) = "d"; %! assert (toupper (a)(3,3,3,3), "D"); diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-base-sparse.cc --- a/libinterp/octave-value/ov-base-sparse.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-base-sparse.cc Thu Jan 02 22:44:37 2014 -0500 @@ -440,11 +440,19 @@ octave_value octave_base_sparse::map (octave_base_value::unary_mapper_t umap) const { + if (umap == umap_xtolower || umap == umap_xtoupper) + return matrix; + // Try the map on the dense value. + // FIXME: We should probably be smarter about this, especially for the + // cases that are expected to return sparse matrices. octave_value retval = this->full_value ().map (umap); // Sparsify the result if possible. + // FIXME: intentionally skip this step for string mappers. Is this wanted? + // FIXME: this will break if some well-meaning person rearranges the + // enum list in ov-base.h. if (umap >= umap_xisalnum && umap <= umap_xtoupper) return retval; diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-float.cc --- a/libinterp/octave-value/ov-float.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-float.cc Thu Jan 02 22:44:37 2014 -0500 @@ -327,8 +327,21 @@ SCALAR_MAPPER (isnan, xisnan); SCALAR_MAPPER (xsignbit, xsignbit); + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return scalar; + default: - return octave_base_value::map (umap); + // FIXME: this will break if some well-meaning person rearranges + // the enum list in ov-base.h. + if (umap >= umap_xisalnum && umap <= umap_xtoupper) + { + octave_value str_conv = convert_to_str (true, true); + return error_state ? octave_value () : str_conv.map (umap); + } + else + return octave_base_value::map (umap); } } diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-flt-re-mat.cc --- a/libinterp/octave-value/ov-flt-re-mat.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-flt-re-mat.cc Thu Jan 02 22:44:37 2014 -0500 @@ -812,8 +812,21 @@ ARRAY_MAPPER (isna, bool, octave_is_NA); ARRAY_MAPPER (xsignbit, float, xsignbit); + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return matrix; + default: - return octave_base_value::map (umap); + // FIXME: this will break if some well-meaning person rearranges + // the enum list in ov-base.h. + if (umap >= umap_xisalnum && umap <= umap_xtoupper) + { + octave_value str_conv = convert_to_str (true, true); + return error_state ? octave_value () : str_conv.map (umap); + } + else + return octave_base_value::map (umap); } } diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-intx.h --- a/libinterp/octave-value/ov-intx.h Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-intx.h Thu Jan 02 22:44:37 2014 -0500 @@ -358,8 +358,15 @@ case umap_finite: return boolNDArray (matrix.dims (), true); + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return matrix; + default: { + // FIXME: we should be able to do better than converting to + // double here. octave_matrix m (array_value ()); return m.map (umap); } @@ -658,6 +665,11 @@ case umap_finite: return true; + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return scalar; + default: { octave_scalar m (scalar_value ()); diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-re-mat.cc --- a/libinterp/octave-value/ov-re-mat.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-re-mat.cc Thu Jan 02 22:44:37 2014 -0500 @@ -935,7 +935,14 @@ ARRAY_MAPPER (isna, bool, octave_is_NA); ARRAY_MAPPER (xsignbit, double, xsignbit); + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return matrix; + default: + // FIXME: this will break if some well-meaning person rearranges + // the enum list in ov-base.h. if (umap >= umap_xisalnum && umap <= umap_xtoupper) { octave_value str_conv = convert_to_str (true, true); diff -r 1461b9cfac4e -r 1b6db9303933 libinterp/octave-value/ov-scalar.cc --- a/libinterp/octave-value/ov-scalar.cc Thu Jan 02 13:23:51 2014 -0800 +++ b/libinterp/octave-value/ov-scalar.cc Thu Jan 02 22:44:37 2014 -0500 @@ -343,7 +343,14 @@ SCALAR_MAPPER (isnan, xisnan); SCALAR_MAPPER (xsignbit, xsignbit); + // Special cases for Matlab compatibility. + case umap_xtolower: + case umap_xtoupper: + return scalar; + default: + // FIXME: this will break if some well-meaning person rearranges + // the enum list in ov-base.h. if (umap >= umap_xisalnum && umap <= umap_xtoupper) { octave_value str_conv = convert_to_str (true, true); diff -r 1461b9cfac4e -r 1b6db9303933 test/build-sparse-tests.sh --- a/test/build-sparse-tests.sh Thu Jan 02 13:23:51 2014 -0800 +++ b/test/build-sparse-tests.sh Thu Jan 02 22:44:37 2014 -0500 @@ -513,14 +513,13 @@ # Specific tests for certain mapper functions cat >>$TESTS <