########################################################################
##
## Copyright (C) 2021 The Octave Project Developers
##
## See the file COPYRIGHT.md in the top-level directory of this
## distribution or .
##
## This file is part of Octave.
##
## Octave is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, see
## .
##
########################################################################
## -*- texinfo -*-
## @deftypefn {} {@var{r} =} convertContainedStringsToChars (@var{a})
## @deftypefnx {} {[@var{r1}, @var{r2}, @dots{}, @var{rn}] =} convertContainedStringsToChars (@var{a1}, @var{a2}, @dots{}, @var{an})
## Convert any string objects within an array into characters arrays.
##
## Like @code{convertCharsToStrings}, convert string scalars into character
## row vectors and string arrays into cell arrays of character row vectors, but
## also perform this conversion recursively within structure and cell arrays.
##
## This function can be used for compatibility with functions that make use of
## characters arrays or cell arrays of strings as input arguments but are not
## compatible with string objects. For example:
##
## @example
## @group
## function example_function (a, b)
## [a, b] = convertContainedStringsToChars (a, b);
## ...
## endfunction
## @end group
## @end example
## or
## @example
## @group
## function varargout = example_function (varargin)
## [vararging{1:nargin}] = convertContainedStringsToChars (varargin{:});
## ...
## endfunction
## @end group
## @end example
##
## @seealso{convertStringsToChars, convertCharsToStrings}
## @end deftypefn
function varargout = convertContainedStringsToChars (varargin)
if (! (nargin < 2 && ! nargout) && (nargin != nargout))
error ("Mismatch between number of input and output arguments.");
endif
varargout = convert_strings_to_chars (varargin);
endfunction
function retval = convert_strings_to_chars (a)
switch (class (a))
case "struct"
retval = structfun (@convert_strings_to_chars, a, "UniformOutput", false);
case "cell"
retval = cellfun (@convert_strings_to_chars, a, "UniformOutput", false);
case "string"
retval = convertStringsToChars (a);
otherwise
retval = a;
endswitch
endfunction
%!test
%! convertContainedStringsToChars;
%! convertContainedStringsToChars ("Octave");
%!test
%! r = convertContainedStringsToChars ("Octave");
%! assert (ischar (r));
%! [r1, r2] = convertContainedStringsToChars ("GNU", "Octave");
%! assert (ischar (r1));
%! assert (ischar (r2));
%!test
%! a = {"Octave 5.1", 2019; ["Octave 5.2", "Octave 6.1"], 2020};
%! r = convertContainedStringsToChars (a);
%! assert (ischar (r{2,1}));
%!test
%! a = struct ("key", "Octave 5.1", "value", 2019);
%! r = convertContainedStringsToChars (a);
%! assert (ischar (r.key));
%! a(2) = struct ("key", "Octave 5.2", "value", 2020);
%! r = convertContainedStringsToChars (a);
%! assert (ischar (r(1).key));
%! assert (ischar (r(2).key));
%!test
%! a1 = {"Octave 5.1", 2019; ["Octave 5.2", "Octave 6.1"], 2020};
%! a2 = struct ("key", "Octave 5.1", "value", 2019);
%! [r1, r2] = convertContainedStringsToChars (a1, a2);
%! assert (ischar (r1{2,1}));
%! assert (ischar (r2.key));
%!test
%! a = containers.Map ({"Octave 5.1", "Octave 5.2"}, [2019, 2020]);
%! r = convertContainedStringsToChars (a);
%! assert (isa (r, "containers.Map"));
%!error r = convertContainedStringsToChars;
%!error r = convertContainedStringsToChars ("GNU", "Octave");
%!error [r1, r2] = convertContainedStringsToChars ("Octave");