GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
strfns.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <cctype>
28 
29 #include <queue>
30 #include <sstream>
31 
32 #include "dMatrix.h"
33 #include "localcharset-wrapper.h"
34 #include "uniconv-wrappers.h"
35 
36 #include "Cell.h"
37 #include "defun.h"
38 #include "error.h"
39 #include "errwarn.h"
40 #include "ov.h"
41 #include "ovl.h"
42 #include "unwind-prot.h"
43 #include "utils.h"
44 
45 #include "oct-string.h"
46 
47 DEFUN (char, args, ,
48  doc: /* -*- texinfo -*-
49 @deftypefn {} {} char (@var{x})
50 @deftypefnx {} {} char (@var{x}, @dots{})
51 @deftypefnx {} {} char (@var{s1}, @var{s2}, @dots{})
52 @deftypefnx {} {} char (@var{cell_array})
53 Create a string array from one or more numeric matrices, character
54 matrices, or cell arrays.
55 
56 Arguments are concatenated vertically. The returned values are padded with
57 blanks as needed to make each row of the string array have the same length.
58 Empty input strings are significant and will concatenated in the output.
59 
60 For numerical input, each element is converted to the corresponding ASCII
61 character. A range error results if an input is outside the ASCII range
62 (0-255).
63 
64 For cell arrays, each element is concatenated separately. Cell arrays
65 converted through @code{char} can mostly be converted back with
66 @code{cellstr}. For example:
67 
68 @example
69 @group
70 char ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
71  @result{} ["abc "
72  " "
73  "98 "
74  "99 "
75  "d "
76  "str1"
77  "half"]
78 @end group
79 @end example
80 @seealso{strvcat, cellstr}
81 @end deftypefn */)
82 {
84 
85  int nargin = args.length ();
86 
87  if (nargin == 0)
88  retval = "";
89  else if (nargin == 1)
90  retval = args(0).convert_to_str (true, true,
91  args(0).is_dq_string () ? '"' : '\'');
92  else
93  {
94  int n_elts = 0;
95 
96  int max_len = 0;
97 
98  std::queue<string_vector> args_as_strings;
99 
100  for (int i = 0; i < nargin; i++)
101  {
102  string_vector s = args(i).xstring_vector_value ("char: unable to convert some args to strings");
103 
104  if (s.numel () > 0)
105  n_elts += s.numel ();
106  else
107  n_elts += 1;
108 
109  int s_max_len = s.max_length ();
110 
111  if (s_max_len > max_len)
112  max_len = s_max_len;
113 
114  args_as_strings.push (s);
115  }
116 
117  string_vector result (n_elts);
118 
119  int k = 0;
120 
121  for (int i = 0; i < nargin; i++)
122  {
123  string_vector s = args_as_strings.front ();
124  args_as_strings.pop ();
125 
126  int n = s.numel ();
127 
128  if (n > 0)
129  {
130  for (int j = 0; j < n; j++)
131  {
132  std::string t = s[j];
133  int t_len = t.length ();
134 
135  if (max_len > t_len)
136  t += std::string (max_len - t_len, ' ');
137 
138  result[k++] = t;
139  }
140  }
141  else
142  result[k++] = std::string (max_len, ' ');
143  }
144 
145  retval = octave_value (result, '\'');
146  }
147 
148  return retval;
149 }
150 
151 /*
152 %!assert (char (), '')
153 %!assert (char (100), "d")
154 %!assert (char (100,100), ["d";"d"])
155 %!assert (char ({100,100}), ["d";"d"])
156 %!assert (char ([100,100]), ["dd"])
157 %!assert (char ({100,{100}}), ["d";"d"])
158 %!assert (char (100, [], 100), ["d";" ";"d"])
159 %!assert (char ({100, [], 100}), ["d";" ";"d"])
160 %!assert (char ({100,{100, {""}}}), ["d";"d";" "])
161 %!assert (char (["a ";"be"], {"c", 100}), ["a ";"be";"c ";"d "])
162 %!assert (char ("a", "bb", "ccc"), ["a "; "bb "; "ccc"])
163 %!assert (char ([65, 83, 67, 73, 73]), "ASCII")
164 
165 %!test
166 %! x = char ("foo", "bar", "foobar");
167 %! assert (x(1,:), "foo ");
168 %! assert (x(2,:), "bar ");
169 %! assert (x(3,:), "foobar");
170 */
171 
172 DEFUN (strvcat, args, ,
173  doc: /* -*- texinfo -*-
174 @deftypefn {} {} strvcat (@var{x})
175 @deftypefnx {} {} strvcat (@var{x}, @dots{})
176 @deftypefnx {} {} strvcat (@var{s1}, @var{s2}, @dots{})
177 @deftypefnx {} {} strvcat (@var{cell_array})
178 Create a character array from one or more numeric matrices, character
179 matrices, or cell arrays.
180 
181 Arguments are concatenated vertically. The returned values are padded with
182 blanks as needed to make each row of the string array have the same length.
183 Unlike @code{char}, empty strings are removed and will not appear in the
184 output.
185 
186 For numerical input, each element is converted to the corresponding ASCII
187 character. A range error results if an input is outside the ASCII range
188 (0-255).
189 
190 For cell arrays, each element is concatenated separately. Cell arrays
191 converted through @code{strvcat} can mostly be converted back with
192 @code{cellstr}. For example:
193 
194 @example
195 @group
196 strvcat ([97, 98, 99], "", @{"98", "99", 100@}, "str1", ["ha", "lf"])
197  @result{} ["abc "
198  "98 "
199  "99 "
200  "d "
201  "str1"
202  "half"]
203 @end group
204 @end example
205 @seealso{char, strcat, cstrcat}
206 @end deftypefn */)
207 {
208  int nargin = args.length ();
209  int n_elts = 0;
210  size_t max_len = 0;
211  std::queue<string_vector> args_as_strings;
212 
213  for (int i = 0; i < nargin; i++)
214  {
215  string_vector s = args(i).xstring_vector_value ("strvcat: unable to convert some args to strings");
216 
217  size_t n = s.numel ();
218 
219  // do not count empty strings in calculation of number of elements
220  if (n > 0)
221  {
222  for (size_t j = 0; j < n; j++)
223  {
224  if (! s[j].empty ())
225  n_elts++;
226  }
227  }
228 
229  size_t s_max_len = s.max_length ();
230 
231  if (s_max_len > max_len)
232  max_len = s_max_len;
233 
234  args_as_strings.push (s);
235  }
236 
237  string_vector result (n_elts);
238 
239  octave_idx_type k = 0;
240 
241  for (int i = 0; i < nargin; i++)
242  {
243  string_vector s = args_as_strings.front ();
244  args_as_strings.pop ();
245 
246  size_t n = s.numel ();
247 
248  if (n > 0)
249  {
250  for (size_t j = 0; j < n; j++)
251  {
252  std::string t = s[j];
253  if (t.length () > 0)
254  {
255  size_t t_len = t.length ();
256 
257  if (max_len > t_len)
258  t += std::string (max_len - t_len, ' ');
259 
260  result[k++] = t;
261  }
262  }
263  }
264  }
265 
266  // Cannot use ovl. Relies on overloaded octave_value call.
267  return octave_value (result, '\'');
268 }
269 
270 /*
271 %!assert (strvcat (""), "")
272 %!assert (strvcat (100) == "d")
273 %!assert (strvcat (100,100), ["d";"d"])
274 %!assert (strvcat ({100,100}), ["d";"d"])
275 %!assert (strvcat ([100,100]), ["dd"])
276 %!assert (strvcat ({100,{100}}), ["d";"d"])
277 %!assert (strvcat (100, [], 100), ["d";"d"])
278 %!assert (strvcat ({100, [], 100}), ["d";"d"])
279 %!assert (strvcat ({100,{100, {""}}}), ["d";"d"])
280 %!assert (strvcat (["a ";"be"], {"c", 100}), ["a ";"be";"c ";"d "])
281 %!assert (strvcat ("a", "bb", "ccc"), ["a "; "bb "; "ccc"])
282 %!assert (strvcat (), "")
283 */
284 
285 DEFUN (ischar, args, ,
286  doc: /* -*- texinfo -*-
287 @deftypefn {} {} ischar (@var{x})
288 Return true if @var{x} is a character array.
289 @seealso{isfloat, isinteger, islogical, isnumeric, isstring, iscellstr, isa}
290 @end deftypefn */)
291 {
292  if (args.length () != 1)
293  print_usage ();
294 
295  return ovl (args(0).is_string ());
296 }
297 
298 /*
299 %!assert (ischar ("a"), true)
300 %!assert (ischar (["ab";"cd"]), true)
301 %!assert (ischar ({"ab"}), false)
302 %!assert (ischar (1), false)
303 %!assert (ischar ([1, 2]), false)
304 %!assert (ischar ([]), false)
305 %!assert (ischar ([1, 2; 3, 4]), false)
306 %!assert (ischar (""), true)
307 %!assert (ischar ("test"), true)
308 %!assert (ischar (["test"; "ing"]), true)
309 %!assert (ischar (struct ("foo", "bar")), false)
310 
311 %!error ischar ()
312 %!error ischar ("test", 1)
313 */
314 
315 static octave_value
316 do_strcmp_fun (const octave_value& arg0, const octave_value& arg1,
317  octave_idx_type n, const char *fcn_name,
318  bool (*array_op) (const Array<char>&, const Array<char>&,
320  bool (*str_op) (const std::string&, const std::string&,
321  std::string::size_type))
322 
323 {
325 
326  bool s1_string = arg0.is_string ();
327  bool s1_cell = arg0.iscell ();
328  bool s2_string = arg1.is_string ();
329  bool s2_cell = arg1.iscell ();
330 
331  if (s1_string && s2_string)
332  retval = array_op (arg0.char_array_value (), arg1.char_array_value (), n);
333  else if ((s1_string && s2_cell) || (s1_cell && s2_string))
334  {
335  octave_value str_val, cell_val;
336 
337  if (s1_string)
338  {
339  str_val = arg0;
340  cell_val = arg1;
341  }
342  else
343  {
344  str_val = arg1;
345  cell_val = arg0;
346  }
347 
348  const Cell cell = cell_val.cell_value ();
349  const string_vector str = str_val.string_vector_value ();
350  octave_idx_type r = str.numel ();
351 
352  if (r == 0 || r == 1)
353  {
354  // Broadcast the string.
355 
356  boolNDArray output (cell_val.dims (), false);
357 
358  std::string s = (r == 0 ? "" : str[0]);
359 
360  if (cell_val.iscellstr ())
361  {
362  const Array<std::string> cellstr = cell_val.cellstr_value ();
363  for (octave_idx_type i = 0; i < cellstr.numel (); i++)
364  output(i) = str_op (cellstr(i), s, n);
365  }
366  else
367  {
368  // FIXME: should we warn here?
369  for (octave_idx_type i = 0; i < cell.numel (); i++)
370  {
371  if (cell(i).is_string ())
372  output(i) = str_op (cell(i).string_value (), s, n);
373  }
374  }
375 
376  retval = output;
377  }
378  else if (r > 1)
379  {
380  if (cell.numel () == 1)
381  {
382  // Broadcast the cell.
383 
384  const dim_vector dv (r, 1);
385  boolNDArray output (dv, false);
386 
387  if (cell(0).is_string ())
388  {
389  const std::string str2 = cell(0).string_value ();
390 
391  for (octave_idx_type i = 0; i < r; i++)
392  output(i) = str_op (str[i], str2, n);
393  }
394 
395  retval = output;
396  }
397  else
398  {
399  // Must match in all dimensions.
400 
401  boolNDArray output (cell.dims (), false);
402 
403  if (cell.numel () == r)
404  {
405  if (cell_val.iscellstr ())
406  {
407  const Array<std::string> cellstr
408  = cell_val.cellstr_value ();
409  for (octave_idx_type i = 0; i < cellstr.numel (); i++)
410  output(i) = str_op (str[i], cellstr(i), n);
411  }
412  else
413  {
414  // FIXME: should we warn here?
415  for (octave_idx_type i = 0; i < r; i++)
416  {
417  if (cell(i).is_string ())
418  output(i) = str_op (str[i],
419  cell(i).string_value (), n);
420  }
421  }
422 
423  retval = output;
424  }
425  else
426  retval = false;
427  }
428  }
429  }
430  else if (s1_cell && s2_cell)
431  {
432  octave_value cell1_val, cell2_val;
433  octave_idx_type r1 = arg0.numel (), r2;
434 
435  if (r1 == 1)
436  {
437  // Make the singleton cell2.
438 
439  cell1_val = arg1;
440  cell2_val = arg0;
441  }
442  else
443  {
444  cell1_val = arg0;
445  cell2_val = arg1;
446  }
447 
448  const Cell cell1 = cell1_val.cell_value ();
449  const Cell cell2 = cell2_val.cell_value ();
450  r1 = cell1.numel ();
451  r2 = cell2.numel ();
452 
453  const dim_vector size1 = cell1.dims ();
454  const dim_vector size2 = cell2.dims ();
455 
456  boolNDArray output (size1, false);
457 
458  if (r2 == 1)
459  {
460  // Broadcast cell2.
461 
462  if (cell2(0).is_string ())
463  {
464  const std::string str2 = cell2(0).string_value ();
465 
466  if (cell1_val.iscellstr ())
467  {
468  const Array<std::string> cellstr = cell1_val.cellstr_value ();
469  for (octave_idx_type i = 0; i < cellstr.numel (); i++)
470  output(i) = str_op (cellstr(i), str2, n);
471  }
472  else
473  {
474  // FIXME: should we warn here?
475  for (octave_idx_type i = 0; i < r1; i++)
476  {
477  if (cell1(i).is_string ())
478  {
479  const std::string str1 = cell1(i).string_value ();
480  output(i) = str_op (str1, str2, n);
481  }
482  }
483  }
484  }
485  }
486  else
487  {
488  if (size1 != size2)
489  error ("%s: nonconformant cell arrays", fcn_name);
490 
491  if (cell1.iscellstr () && cell2.iscellstr ())
492  {
493  const Array<std::string> cellstr1 = cell1_val.cellstr_value ();
494  const Array<std::string> cellstr2 = cell2_val.cellstr_value ();
495  for (octave_idx_type i = 0; i < r1; i++)
496  output (i) = str_op (cellstr1(i), cellstr2(i), n);
497  }
498  else
499  {
500  // FIXME: should we warn here?
501  for (octave_idx_type i = 0; i < r1; i++)
502  {
503  if (cell1(i).is_string () && cell2(i).is_string ())
504  {
505  const std::string str1 = cell1(i).string_value ();
506  const std::string str2 = cell2(i).string_value ();
507  output(i) = str_op (str1, str2, n);
508  }
509  }
510  }
511  }
512 
513  retval = output;
514  }
515  else
516  retval = false;
517 
518  return retval;
519 }
520 
521 
522 // These are required so that they match the same signature as strncmp
523 // and strncmpi and can therefore be used in do_strcmp_fun.
524 
525 template <typename T, typename T_size_type>
526 static bool
527 strcmp_ignore_n (const T& s1, const T& s2, T_size_type)
528 { return octave::string::strcmp (s1, s2); }
529 
530 template <typename T, typename T_size_type>
531 static bool
532 strcmpi_ignore_n (const T& s1, const T& s2, T_size_type)
533 { return octave::string::strcmpi (s1, s2); }
534 
535 
536 DEFUN (strcmp, args, ,
537  doc: /* -*- texinfo -*-
538 @deftypefn {} {} strcmp (@var{s1}, @var{s2})
539 Return 1 if the character strings @var{s1} and @var{s2} are the same,
540 and 0 otherwise.
541 
542 If either @var{s1} or @var{s2} is a cell array of strings, then an array
543 of the same size is returned, containing the values described above for
544 every member of the cell array. The other argument may also be a cell
545 array of strings (of the same size or with only one element), char matrix
546 or character string.
547 
548 @strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmp
549 function returns 1 if the character strings are equal, and 0 otherwise.
550 This is just the opposite of the corresponding C library function.
551 @seealso{strcmpi, strncmp, strncmpi}
552 @end deftypefn */)
553 {
554  if (args.length () != 2)
555  print_usage ();
556 
557  return ovl (do_strcmp_fun (args(0), args(1), 0, "strcmp",
558  strcmp_ignore_n, strcmp_ignore_n));
559 }
560 
561 /*
562 %!shared x
563 %! x = char (zeros (0, 2));
564 %!assert (strcmp ("", x), false)
565 %!assert (strcmp (x, ""), false)
566 %!assert (strcmp (x, x), true)
567 ## %!assert (strcmp ({""}, x), true)
568 ## %!assert (strcmp ({x}, ""), false)
569 ## %!assert (strcmp ({x}, x), true)
570 ## %!assert (strcmp ("", {x}), false)
571 ## %!assert (strcmp (x, {""}), false)
572 ## %!assert (strcmp (x, {x}), true)
573 ## %!assert (strcmp ({x; x}, ""), [false; false])
574 ## %!assert (strcmp ({x; x}, {""}), [false; false])
575 ## %!assert (strcmp ("", {x; x}), [false; false])
576 ## %!assert (strcmp ({""}, {x; x}), [false; false])
577 %!assert (strcmp ({"foo"}, x), false)
578 %!assert (strcmp ({"foo"}, "foo"), true)
579 %!assert (strcmp ({"foo"}, x), false)
580 %!assert (strcmp (x, {"foo"}), false)
581 %!assert (strcmp ("foo", {"foo"}), true)
582 %!assert (strcmp (x, {"foo"}), false)
583 %!shared y
584 %! y = char (zeros (2, 0));
585 %!assert (strcmp ("", y), false)
586 %!assert (strcmp (y, ""), false)
587 %!assert (strcmp (y, y), true)
588 %!assert (strcmp ({""}, y), [true; true])
589 %!assert (strcmp ({y}, ""), true)
590 %!assert (strcmp ({y}, y), [true; true])
591 %!assert (strcmp ("", {y}), true)
592 %!assert (strcmp (y, {""}), [true; true])
593 %!assert (strcmp (y, {y}), [true; true])
594 %!assert (strcmp ({y; y}, ""), [true; true])
595 %!assert (strcmp ({y; y}, {""}), [true; true])
596 %!assert (strcmp ("", {y; y}), [true; true])
597 %!assert (strcmp ({""}, {y; y}), [true; true])
598 %!assert (strcmp ({"foo"}, y), [false; false])
599 %!assert (strcmp ({"foo"}, y), [false; false])
600 %!assert (strcmp (y, {"foo"}), [false; false])
601 %!assert (strcmp (y, {"foo"}), [false; false])
602 %!assert (strcmp ("foobar", "foobar"), true)
603 %!assert (strcmp ("foobar", "fooBar"), false)
604 %!assert (strcmp ("fooba", "foobar"), false)
605 
606 %!error strcmp ()
607 %!error strcmp ("foo", "bar", 3)
608 */
609 
610 DEFUN (strncmp, args, ,
611  doc: /* -*- texinfo -*-
612 @deftypefn {} {} strncmp (@var{s1}, @var{s2}, @var{n})
613 Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2}
614 are the same, and 0 otherwise.
615 
616 @example
617 @group
618 strncmp ("abce", "abcd", 3)
619  @result{} 1
620 @end group
621 @end example
622 
623 If either @var{s1} or @var{s2} is a cell array of strings, then an array
624 of the same size is returned, containing the values described above for
625 every member of the cell array. The other argument may also be a cell
626 array of strings (of the same size or with only one element), char matrix
627 or character string.
628 
629 @example
630 @group
631 strncmp ("abce", @{"abcd", "bca", "abc"@}, 3)
632  @result{} [1, 0, 1]
633 @end group
634 @end example
635 
636 @strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmp
637 function returns 1 if the character strings are equal, and 0 otherwise.
638 This is just the opposite of the corresponding C library function.
639 @seealso{strncmpi, strcmp, strcmpi}
640 @end deftypefn */)
641 {
642  if (args.length () != 3)
643  print_usage ();
644 
645  octave_idx_type n = args(2).idx_type_value ();
646 
647  if (n > 0)
648  return ovl (do_strcmp_fun (args(0), args(1), n, "strncmp",
651  else
652  error ("strncmp: N must be greater than 0");
653 }
654 
655 /*
656 %!assert (strncmp ("abce", "abc", 3), true)
657 %!assert (strncmp ("abce", "aBc", 3), false)
658 %!assert (strncmp (100, 100, 1), false)
659 %!assert (strncmp ("abce", {"abcd", "bca", "abc"}, 3), logical ([1, 0, 1]))
660 %!assert (strncmp ("abc", {"abcd", "bca", "abc"}, 4), logical ([0, 0, 0]))
661 %!assert (strncmp ({"abcd", "bca", "abc"},"abce", 3), logical ([1, 0, 1]))
662 %!assert (strncmp ({"abcd", "bca", "abc"},{"abcd", "bca", "abe"}, 3), logical ([1, 1, 0]))
663 %!assert (strncmp ("abc", {"abcd", 10}, 2), logical ([1, 0]))
664 
665 %!error strncmp ()
666 %!error strncmp ("abc", "def")
667 */
668 
669 DEFUNX ("strcmpi", Fstrcmpi, args, ,
670  doc: /* -*- texinfo -*-
671 @deftypefn {} {} strcmpi (@var{s1}, @var{s2})
672 Return 1 if the character strings @var{s1} and @var{s2} are the same,
673 disregarding case of alphabetic characters, and 0 otherwise.
674 
675 If either @var{s1} or @var{s2} is a cell array of strings, then an array
676 of the same size is returned, containing the values described above for
677 every member of the cell array. The other argument may also be a cell
678 array of strings (of the same size or with only one element), char matrix
679 or character string.
680 
681 @strong{Caution:} For compatibility with @sc{matlab}, Octave's strcmp
682 function returns 1 if the character strings are equal, and 0 otherwise.
683 This is just the opposite of the corresponding C library function.
684 
685 @strong{Caution:} National alphabets are not supported.
686 @seealso{strcmp, strncmp, strncmpi}
687 @end deftypefn */)
688 {
689  if (args.length () != 2)
690  print_usage ();
691 
692  return ovl (do_strcmp_fun (args(0), args(1), 0, "strcmpi",
693  strcmpi_ignore_n, strcmpi_ignore_n));
694 }
695 
696 /*
697 %!assert (strcmpi ("abc123", "ABC123"), true)
698 */
699 
700 DEFUNX ("strncmpi", Fstrncmpi, args, ,
701  doc: /* -*- texinfo -*-
702 @deftypefn {} {} strncmpi (@var{s1}, @var{s2}, @var{n})
703 Return 1 if the first @var{n} character of @var{s1} and @var{s2} are the
704 same, disregarding case of alphabetic characters, and 0 otherwise.
705 
706 If either @var{s1} or @var{s2} is a cell array of strings, then an array
707 of the same size is returned, containing the values described above for
708 every member of the cell array. The other argument may also be a cell
709 array of strings (of the same size or with only one element), char matrix
710 or character string.
711 
712 @strong{Caution:} For compatibility with @sc{matlab}, Octave's strncmpi
713 function returns 1 if the character strings are equal, and 0 otherwise.
714 This is just the opposite of the corresponding C library function.
715 
716 @strong{Caution:} National alphabets are not supported.
717 @seealso{strncmp, strcmp, strcmpi}
718 @end deftypefn */)
719 {
720  if (args.length () != 3)
721  print_usage ();
722 
723  octave_idx_type n = args(2).idx_type_value ();
724 
725  if (n > 0)
726  return ovl (do_strcmp_fun (args(0), args(1), n, "strncmpi",
729  else
730  error ("strncmpi: N must be greater than 0");
731 }
732 
733 /*
734 %!assert (strncmpi ("abc123", "ABC456", 3), true)
735 */
736 
737 DEFUN (__native2unicode__, args, ,
738  doc: /* -*- texinfo -*-
739 @deftypefn {} {@var{utf8_str} =} __native2unicode__ (@var{native_bytes}, @var{codepage})
740 Convert byte stream @var{native_bytes} to UTF-8 using @var{codepage}.
741 
742 @seealso{native2unicode, __unicode2native__}
743 @end deftypefn */)
744 {
745  int nargin = args.length ();
746 
747  if (nargin != 2)
748  print_usage ();
749 
750  if (args(0).is_string ())
751  return ovl (args(0));
752 
753  std::string tmp = args(1).xstring_value ("CODEPAGE must be a string");
754  const char *codepage
755  = (tmp.empty () ? octave_locale_charset_wrapper () : tmp.c_str ());
756 
757  charNDArray native_bytes = args(0).char_array_value ();
758 
759  const char *src = native_bytes.data ();
760  size_t srclen = native_bytes.numel ();
761 
762  size_t length;
763  uint8_t *utf8_str = nullptr;
764 
766 
767  utf8_str = octave_u8_conv_from_encoding (codepage, src, srclen, &length);
768 
769  if (! utf8_str)
770  {
771  if (errno == ENOSYS)
772  error ("native2unicode: iconv() is not supported. Installing GNU "
773  "libiconv and then re-compiling Octave could fix this.");
774  else
775  error ("native2unicode: converting from codepage '%s' to UTF-8: %s",
776  codepage, std::strerror (errno));
777  }
778 
779  frame.add_fcn (::free, static_cast<void *> (utf8_str));
780 
781  octave_idx_type len = length;
782 
783  charNDArray retval (dim_vector (1, len));
784 
785  for (octave_idx_type i = 0; i < len; i++)
786  retval.xelem(i) = utf8_str[i];
787 
788  return ovl (retval);
789 }
790 
791 DEFUN (__unicode2native__, args, ,
792  doc: /* -*- texinfo -*-
793 @deftypefn {} {@var{native_bytes} =} __unicode2native__ (@var{utf8_str}, @var{codepage})
794 Convert UTF-8 string @var{utf8_str} to byte stream @var{native_bytes} using
795 @var{codepage}.
796 
797 @seealso{unicode2native, __native2unicode__}
798 @end deftypefn */)
799 {
800  int nargin = args.length ();
801 
802  if (nargin != 2)
803  print_usage ();
804 
805  std::string tmp = args(1).xstring_value ("CODEPAGE must be a string");
806  const char *codepage
807  = (tmp.empty () ? octave_locale_charset_wrapper () : tmp.c_str ());
808 
809  charNDArray utf8_str = args(0).xchar_array_value ("UTF8_STR must be a string");
810 
811  const uint8_t *src = reinterpret_cast<const uint8_t *> (utf8_str.data ());
812  size_t srclen = utf8_str.numel ();
813 
814  size_t length;
815  char *native_bytes = nullptr;
816 
818 
819  native_bytes = octave_u8_conv_to_encoding (codepage, src, srclen, &length);
820 
821  if (! native_bytes)
822  {
823  if (errno == ENOSYS)
824  error ("unicode2native: iconv() is not supported. Installing GNU "
825  "libiconv and then re-compiling Octave could fix this.");
826  else
827  error ("unicode2native: converting from UTF-8 to codepage '%s': %s",
828  codepage, std::strerror (errno));
829  }
830 
831  frame.add_fcn (::free, static_cast<void *> (native_bytes));
832 
833  octave_idx_type len = length;
834 
835  uint8NDArray retval (dim_vector (1, len));
836 
837  for (octave_idx_type i = 0; i < len; i++)
838  retval.xelem(i) = native_bytes[i];
839 
840  return ovl (retval);
841 }
842 
843 DEFUN (list_in_columns, args, ,
844  doc: /* -*- texinfo -*-
845 @deftypefn {} {} list_in_columns (@var{arg}, @var{width}, @var{prefix})
846 Return a string containing the elements of @var{arg} listed in columns with
847 an overall maximum width of @var{width} and optional prefix @var{prefix}.
848 
849 The argument @var{arg} must be a cell array of character strings or a
850 character array.
851 
852 If @var{width} is not specified or is an empty matrix, or less than or equal
853 to zero, the width of the terminal screen is used. Newline characters are
854 used to break the lines in the output string. For example:
855 @c Set example in small font to prevent overfull line
856 
857 @smallexample
858 @group
859 list_in_columns (@{"abc", "def", "ghijkl", "mnop", "qrs", "tuv"@}, 20)
860  @result{} abc mnop
861  def qrs
862  ghijkl tuv
863 
864 whos ans
865  @result{}
866  Variables in the current scope:
867 
868  Attr Name Size Bytes Class
869  ==== ==== ==== ===== =====
870  ans 1x37 37 char
871 
872  Total is 37 elements using 37 bytes
873 @end group
874 @end smallexample
875 
876 @seealso{terminal_size}
877 @end deftypefn */)
878 {
879  int nargin = args.length ();
880 
882  print_usage ();
883 
884  string_vector s = args(0).xstring_vector_value ("list_in_columns: ARG must be a cellstr or char array");
885 
886  int width = -1;
887 
888  if (nargin > 1 && ! args(1).isempty ())
889  width = args(1).xint_value ("list_in_columns: WIDTH must be an integer");
890 
891  std::string prefix;
892 
893  if (nargin > 2)
894  prefix = args(2).xstring_value ("list_in_columns: PREFIX must be a string");
895 
896  std::ostringstream buf;
897 
898  s.list_in_columns (buf, width, prefix);
899 
900  return ovl (buf.str ());
901 }
902 
903 /*
904 %!test
905 %! input = {"abc", "def", "ghijkl", "mnop", "qrs", "tuv"};
906 %! result = "abc mnop\ndef qrs\nghijkl tuv\n";
907 %! assert (list_in_columns (input, 20), result);
908 %!test
909 %! input = char ("abc", "def", "ghijkl", "mnop", "qrs", "tuv");
910 %! result = "abc mnop \ndef qrs \nghijkl tuv \n";
911 %! assert (list_in_columns (input, 20), result);
912 %!test
913 %! input = char ("abc", "def", "ghijkl", "mnop", "qrs", "tuv");
914 %! result = " abc mnop \n def qrs \n ghijkl tuv \n";
915 %! assert (list_in_columns (input, 20, " "), result);
916 
917 %!error list_in_columns ()
918 %!error list_in_columns (["abc", "def"], 20, 2)
919 %!error list_in_columns (["abc", "def"], 20, " ", 3)
920 %!error <list_in_columns: WIDTH must be an integer> list_in_columns (["abc", "def"], "a")
921 */
OCTAVE_EXPORT octave_value_list ischar
Definition: data.cc:3212
Definition: Cell.h:37
std::string string_value(bool force=false) const
Definition: ov.h:955
bool isempty(void) const
Definition: ov.h:529
const T * data(void) const
Definition: Array.h:582
uint8_t * octave_u8_conv_from_encoding(const char *fromcode, const char *src, size_t srclen, size_t *lengthp)
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
s2
Definition: sub2ind.cc:107
char * octave_u8_conv_to_encoding(const char *tocode, const uint8_t *src, size_t srclen, size_t *lengthp)
for large enough k
Definition: lu.cc:617
void add_fcn(void(*fcn)(void))
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void error(const char *fmt,...)
Definition: error.cc:578
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:442
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:997
s
Definition: file-io.cc:2729
bool is_dq_string(void) const
Definition: ov.h:583
charNDArray char_array_value(bool frc_str_conv=false) const
Definition: ov.h:878
bool iscellstr(void) const
Definition: ov.h:543
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1736
bool iscellstr(void) const
Definition: Cell.cc:107
octave_idx_type numel(const octave_value_list &idx)
Definition: ov.h:412
bool iscell(void) const
Definition: ov.h:536
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
Definition: oct-string.cc:112
std::string str
Definition: hash.cc:118
dim_vector dims(void) const
Definition: ov.h:469
#define DEFUNX(name, fname, args_name, nargout_name, doc)
Macro to define a builtin function with certain internal name.
Definition: defun.h:82
double tmp
Definition: data.cc:6252
octave_value retval
Definition: data.cc:6246
octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
Definition: ov.h:1251
With real return the complex result
Definition: data.cc:3260
octave::unwind_protect frame
Definition: graphics.cc:12190
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
bool strcmpi(const T &str_a, const T &str_b)
True if strings are the same, ignoring case.
Definition: oct-string.cc:129
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
octave_idx_type length(void) const
Definition: ovl.h:96
const char * octave_locale_charset_wrapper(void)
args.length() nargin
Definition: file-io.cc:589
for i
Definition: data.cc:5264
string_vector string_vector_value(bool pad=false) const
Definition: ov.h:958
bool is_string(void) const
Definition: ov.h:577
bool strncmp(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same.
Definition: oct-string.cc:146
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
octave_idx_type length(void) const
bool strncmpi(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same, ignoring case.
Definition: oct-string.cc:165
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
Array< std::string > cellstr_value(void) const
Definition: ov.h:967
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
dim_vector dv
Definition: sub2ind.cc:263
Cell cell_value(void) const