GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
utils.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cerrno>
31 #include <cstring>
32 
33 #include <fstream>
34 #include <limits>
35 #include <ostream>
36 #include <string>
37 
38 #include "dir-ops.h"
39 #include "file-ops.h"
40 #include "file-stat.h"
41 #include "lo-mappers.h"
42 #include "lo-utils.h"
43 #include "nanosleep-wrapper.h"
44 #include "oct-cmplx.h"
45 #include "oct-env.h"
46 #include "oct-locbuf.h"
47 #include "oct-string.h"
48 #include "pathsearch.h"
49 #include "quit.h"
50 #include "str-vec.h"
51 #include "vasprintf-wrapper.h"
52 
53 #include "Cell.h"
54 #include "defun.h"
55 #include "error.h"
56 #include "errwarn.h"
57 #include "graphics.h"
58 #include "interpreter-private.h"
59 #include "interpreter.h"
60 #include "lex.h"
61 #include "load-path.h"
62 #include "oct-errno.h"
63 #include "oct-hist.h"
64 #include "ovl.h"
65 #include "ov-range.h"
66 #include "pager.h"
67 #include "parse.h"
68 #include "sysdep.h"
69 #include "unwind-prot.h"
70 #include "utils.h"
71 #include "variables.h"
72 
73 namespace octave
74 {
75  // Return TRUE if S is a valid identifier.
76 
77  bool valid_identifier (const char *s)
78  {
79  if (! s || ! (isalpha (*s) || *s == '_'))
80  return false;
81 
82  while (*++s != '\0')
83  if (! (isalnum (*s) || *s == '_'))
84  return false;
85 
86  return true;
87  }
88 
89  bool valid_identifier (const std::string& s)
90  {
91  return valid_identifier (s.c_str ());
92  }
93 }
94 
95 DEFUN (isvarname, args, ,
96  doc: /* -*- texinfo -*-
97 @deftypefn {} {} isvarname (@var{name})
98 Return true if @var{name} is a valid variable name.
99 
100 A valid variable name is composed of letters, digits, and underscores ("_"),
101 and the first character must not be a digit.
102 @seealso{iskeyword, exist, who}
103 @end deftypefn */)
104 {
105  if (args.length () != 1)
106  print_usage ();
107 
108  octave_value retval = false;
109 
110  if (args(0).is_string ())
111  {
112  std::string varname = args(0).string_value ();
113 
114  retval = (octave::valid_identifier (varname)
115  && ! octave::iskeyword (varname));
116  }
117 
118  return retval;
119 }
120 
121 /*
122 %!assert (isvarname ("foo"), true)
123 %!assert (isvarname ("_foo"), true)
124 %!assert (isvarname ("_1"), true)
125 %!assert (isvarname ("1foo"), false)
126 %!assert (isvarname (""), false)
127 %!assert (isvarname (12), false)
128 %!assert (isvarname ("foo+bar"), false)
129 
130 %!error isvarname ()
131 %!error isvarname ("foo", "bar")
132 */
133 
134 namespace octave
135 {
136  // Return TRUE if F and G are both names for the same file.
137 
138  bool same_file (const std::string& f, const std::string& g)
139  {
140  return same_file_internal (f, g);
141  }
142 }
143 
144 DEFUN (is_same_file, args, ,
145  doc: /* -*- texinfo -*-
146 @deftypefn {} {@var{same} =} is_same_file (@var{filepath1}, @var{filepath2})
147 Return true if @var{filepath1} and @var{filepath2} refer to the same file.
148 
149 If either @var{filepath1} or @var{filepath2} is a cell array of strings, then
150 an array of the same size is returned, containing the values described above
151 for every member of the cell array. The other argument may also be a cell
152 array of strings (of the same size) or a string.
153 
154 Programming Notes: Depending on the operating system and file system, the same
155 file or folder can be referred to with different paths. In particular, paths
156 on the Windows platform may differ in case (@file{file1} vs.@: @file {FILE1}),
157 file separator (@samp{\} vs.@: @samp{/}), and format (@file{A~spaces.txt} (8.3
158 convention) vs.@: @file{A filename with spaces.txt}). This function returns
159 true if the paths in @var{filepath1} and @var{filepath2} actually refer to the
160 same file or folder, and false otherwise.
161 
162 Note that unlike @code{strcmp}, this function requires that @var{filepath1}
163 and @var{filepath2} exist, as well as point to the same location, in order to
164 return true.
165 
166 @seealso{canonicalize_file_name, strcmp}
167 @end deftypefn */)
168 {
169  if (args.length () != 2)
170  print_usage ();
171 
173 
174  bool s1_string = args(0).is_string ();
175  bool s1_cellstr = args(0).iscellstr ();
176  bool s2_string = args(1).is_string ();
177  bool s2_cellstr = args(1).iscellstr ();
178 
179  if (s1_string && s2_string)
180  {
181  std::string file1 = args(0).string_value ();
182  std::string file2 = args(1).string_value ();
183 
184  retval = octave::same_file (file1, file2);
185  }
186  else if ((s1_string && s2_cellstr) || (s1_cellstr && s2_string))
187  {
188  octave_value str_arg, cellstr_arg;
189 
190  if (s1_string)
191  {
192  str_arg = args(0);
193  cellstr_arg = args(1);
194  }
195  else
196  {
197  str_arg = args(1);
198  cellstr_arg = args(0);
199  }
200 
201  const Array<std::string> cellstr = cellstr_arg.cellstr_value ();
202  const std::string str = str_arg.string_value ();
203 
204  boolNDArray output (cellstr.dims (), false);
205 
206  for (octave_idx_type idx = 0; idx < cellstr.numel (); idx++)
207  output(idx) = octave::same_file (str, cellstr(idx));
208 
209  retval = output;
210  }
211  else if (s1_cellstr && s2_cellstr)
212  {
213  const Array<std::string> cellstr1 = args(0).cellstr_value ();
214  const Array<std::string> cellstr2 = args(1).cellstr_value ();
215 
216  const dim_vector size1 = cellstr1.dims ();
217  const dim_vector size2 = cellstr2.dims ();
218 
219  if (size1 != size2)
220  error ("is_same_file: cellstr arrays FILEPATH1 and FILEPATH2 must be the same size");
221 
222  boolNDArray output (size1, false);
223 
224  for (octave_idx_type idx = 0; idx < cellstr1.numel (); idx++)
225  output(idx) = octave::same_file (cellstr1(idx), cellstr2(idx));
226 
227  retval = output;
228  }
229  else
230  error ("is_same_file: FILEPATH1 and FILEPATH2 must be strings or cell arrays of strings");
231 
232  return retval;
233 }
234 
235 /*
236 %!testif ; ! ispc ()
237 %! assert (is_same_file ("~", tilde_expand ("~")));
238 %!testif ; ispc ()
239 %! assert (is_same_file (tolower (getenv ("OCTAVE_HOME")),
240 %! toupper (getenv ("OCTAVE_HOME"))), true);
241 %!assert (is_same_file ({pwd(), ".", tempdir()}, canonicalize_file_name (".")),
242 %! [true, true, false])
243 
244 %!error is_same_file ()
245 %!error is_same_file ("foo")
246 %!error is_same_file ("foo", "bar", "baz")
247 %!error <must be strings or cell arrays of strings> is_same_file ("foo", 1)
248 %!error <must be strings or cell arrays of strings> is_same_file (1, "foo")
249 %!error <must be strings or cell arrays of strings> is_same_file ("foo", {1})
250 %!error <must be strings or cell arrays of strings> is_same_file ({1}, "foo")
251 %!error <arrays .* must be the same size> is_same_file ({"1", "2"}, {"1"; "2"})
252 */
253 
254 
255 namespace octave
256 {
257  int almost_match (const std::string& std, const std::string& s,
258  int min_match_len, int case_sens)
259  {
260  int stdlen = std.length ();
261  int slen = s.length ();
262 
263  return (slen <= stdlen
264  && slen >= min_match_len
265  && (case_sens
266  ? (strncmp (std.c_str (), s.c_str (), slen) == 0)
267  : (octave_strncasecmp (std.c_str (), s.c_str (), slen) == 0)));
268  }
269 
270  // Ugh.
271 
272  int keyword_almost_match (const char * const *std, int *min_len,
273  const std::string& s,
274  int min_toks_to_match, int max_toks)
275  {
276  int status = 0;
277  int tok_count = 0;
278  int toks_matched = 0;
279 
280  if (s.empty () || max_toks < 1)
281  return status;
282 
283  char *kw = strsave (s.c_str ());
284 
285  char *t = kw;
286  while (*t != '\0')
287  {
288  if (*t == '\t')
289  *t = ' ';
290  t++;
291  }
292 
293  char *beg = kw;
294  while (*beg == ' ')
295  beg++;
296 
297  if (*beg == '\0')
298  return status;
299 
300  const char **to_match = new const char * [max_toks + 1];
301  const char * const *s1 = std;
302  const char **s2 = to_match;
303 
304  if (! s1 || ! s2)
305  goto done;
306 
307  s2[tok_count] = beg;
308  char *end;
309  while ((end = strchr (beg, ' ')) != nullptr)
310  {
311  *end = '\0';
312  beg = end + 1;
313 
314  while (*beg == ' ')
315  beg++;
316 
317  if (*beg == '\0')
318  break;
319 
320  tok_count++;
321  if (tok_count >= max_toks)
322  goto done;
323 
324  s2[tok_count] = beg;
325  }
326  s2[tok_count+1] = nullptr;
327 
328  s2 = to_match;
329 
330  for (;;)
331  {
332  if (! almost_match (*s1, *s2, min_len[toks_matched], 0))
333  goto done;
334 
335  toks_matched++;
336 
337  s1++;
338  s2++;
339 
340  if (! *s2)
341  {
342  status = (toks_matched >= min_toks_to_match);
343  goto done;
344  }
345 
346  if (! *s1)
347  goto done;
348  }
349 
350  done:
351 
352  delete [] kw;
353  delete [] to_match;
354 
355  return status;
356  }
357 
358  // See if the given file is in the path.
359 
360  std::string search_path_for_file (const std::string& path,
361  const string_vector& names)
362  {
363  directory_path p (path);
364 
365  return sys::env::make_absolute (p.find_first_of (names.std_list ()));
366  }
367 
368  // Find all locations of the given file in the path.
369 
371  const string_vector& names)
372  {
373  directory_path p (path);
374 
375  string_vector sv = p.find_all_first_of (names.std_list ());
376 
377  octave_idx_type len = sv.numel ();
378 
379  for (octave_idx_type i = 0; i < len; i++)
380  sv[i] = sys::env::make_absolute (sv[i]);
381 
382  return sv;
383  }
384 
386  {
387  octave_idx_type len = sv.numel ();
388 
390 
391  for (octave_idx_type i = 0; i < len; i++)
392  retval[i] = sys::env::make_absolute (sv[i]);
393 
394  return retval;
395  }
396 }
397 
398 DEFMETHOD (file_in_loadpath, interp, args, ,
399  doc: /* -*- texinfo -*-
400 @deftypefn {} {@var{fname} =} file_in_loadpath (@var{file})
401 @deftypefnx {} {@var{fname} =} file_in_loadpath (@var{file}, "all")
402 Return the absolute name of @var{file} if it can be found in the list of
403 directories specified by @code{path}.
404 
405 If no file is found, return an empty character string.
406 
407 When @var{file} is already an absolute name, the name is checked against the
408 file system instead of Octave's loadpath. In this case, if @var{file} exists
409 it will be returned in @var{fname}, otherwise an empty string is returned.
410 
411 If the first argument is a cell array of strings, search each directory of
412 the loadpath for element of the cell array and return the first that
413 matches.
414 
415 If the second optional argument @qcode{"all"} is supplied, return a cell
416 array containing the list of all files that have the same name in the path.
417 If no files are found, return an empty cell array.
418 @seealso{file_in_path, dir_in_loadpath, path}
419 @end deftypefn */)
420 {
421  int nargin = args.length ();
422 
423  if (nargin < 1 || nargin > 2)
424  print_usage ();
425 
426  string_vector names = args(0).xstring_vector_value ("file_in_loadpath: FILE argument must be a string");
427 
428  if (names.empty ())
429  error ("file_in_loadpath: FILE argument must not be empty");
430 
431  octave::load_path& lp = interp.get_load_path ();
432 
433  if (nargin == 1)
434  return ovl (octave::sys::env::make_absolute (lp.find_first_of (names)));
435  else
436  {
437  std::string opt = args(1).xstring_value ("file_in_loadpath: optional second argument must be a string");
438 
439  if (opt != "all")
440  error (R"(file_in_loadpath: "all" is only valid second argument)");
441 
442  return ovl (Cell (octave::make_absolute (lp.find_all_first_of (names))));
443  }
444 }
445 
446 /*
447 %!test
448 %! f = file_in_loadpath ("plot.m");
449 %! assert (ischar (f));
450 %! assert (! isempty (f));
451 
452 %!test
453 %! f = file_in_loadpath ("$$probably_!! _not_&&_a_!! _file$$");
454 %! assert (f, "");
455 
456 %!test
457 %! lst = file_in_loadpath ("$$probably_!! _not_&&_a_!! _file$$", "all");
458 %! assert (lst, {});
459 
460 %!error file_in_loadpath ()
461 %!error file_in_loadpath ("foo", "bar", 1)
462 %!error file_in_loadpath ([])
463 %!error file_in_loadpath ("plot.m", "bar")
464 */
465 
466 DEFUN (file_in_path, args, ,
467  doc: /* -*- texinfo -*-
468 @deftypefn {} {} file_in_path (@var{path}, @var{file})
469 @deftypefnx {} {} file_in_path (@var{path}, @var{file}, "all")
470 Return the absolute name of @var{file} if it can be found in @var{path}.
471 
472 The value of @var{path} should be a colon-separated list of directories in
473 the format described for @code{path}. If no file is found, return an empty
474 character string. For example:
475 
476 @example
477 @group
478 file_in_path (EXEC_PATH, "sh")
479  @result{} "/bin/sh"
480 @end group
481 @end example
482 
483 If the second argument is a cell array of strings, search each directory of
484 the path for element of the cell array and return the first that matches.
485 
486 If the third optional argument @qcode{"all"} is supplied, return a cell
487 array containing the list of all files that have the same name in the path.
488 If no files are found, return an empty cell array.
489 @seealso{file_in_loadpath, dir_in_loadpath, path}
490 @end deftypefn */)
491 {
492  int nargin = args.length ();
493 
494  if (nargin < 2 || nargin > 3)
495  print_usage ();
496 
497  std::string path = args(0).xstring_value ("file_in_path: PATH must be a string");
498 
499  string_vector names = args(1).xstring_vector_value ("file_in_path: FILE argument must be a string");
500 
501  if (names.empty ())
502  error ("file_in_path: FILE argument must not be empty");
503 
504  if (nargin == 2)
505  return ovl (octave::search_path_for_file (path, names));
506  else
507  {
508  std::string opt = args(2).xstring_value ("file_in_path: optional third argument must be a string");
509 
510  if (opt != "all")
511  error (R"(file_in_path: "all" is only valid third argument)");
512 
514  }
515 }
516 
517 /*
518 %!test
519 %! f = file_in_path (path (), "plot.m");
520 %! assert (ischar (f));
521 %! assert (! isempty (f));
522 
523 %!test
524 %! f = file_in_path (path (), "$$probably_!! _not_&&_a_!! _file$$");
525 %! assert (f, "");
526 
527 %!test
528 %! lst = file_in_path (path (), "$$probably_!! _not_&&_a_!! _file$$", "all");
529 %! assert (lst, {});
530 
531 %!error file_in_path ()
532 %!error file_in_path ("foo")
533 %!error file_in_path ("foo", "bar", "baz", 1)
534 %!error file_in_path ([])
535 %!error file_in_path (path (), [])
536 %!error file_in_path (path (), "plot.m", "bar")
537 */
538 
539 namespace octave
540 {
541  std::string file_in_path (const std::string& name, const std::string& suffix)
542  {
543  std::string nm = name;
544 
545  if (! suffix.empty ())
546  nm.append (suffix);
547 
548  load_path& lp = __get_load_path__ ("file_in_path");
549 
550  return sys::env::make_absolute (lp.find_file (nm));
551  }
552 
553  std::string find_data_file_in_load_path (const std::string& fcn,
554  const std::string& file,
555  bool require_regular_file)
556  {
557  std::string fname = file;
558 
559  if (! (sys::env::absolute_pathname (fname)
561  {
562  // Load path will also search "." first, but we don't want to
563  // issue a warning if the file is found in the current directory,
564  // so do an explicit check for that.
565  sys::file_stat fs (fname);
566 
567  bool local_file_ok
568  = fs.exists () && (fs.is_reg () || ! require_regular_file);
569 
570  if (! local_file_ok)
571  {
572  load_path& lp = __get_load_path__ ("find_data_file_in_load_path");
573 
574  // Not directly found; search load path.
575  std::string tmp = sys::env::make_absolute (lp.find_file (fname));
576 
577  if (! tmp.empty ())
578  {
579  warn_data_file_in_path (fcn, tmp);
580 
581  fname = tmp;
582  }
583  }
584  }
585 
586  return fname;
587  }
588 
589  // See if there is an function file in the path.
590  // If so, return the full path to the file.
591 
592  std::string fcn_file_in_path (const std::string& name)
593  {
594  std::string retval;
595 
596  int len = name.length ();
597 
598  if (len > 0)
599  {
601  {
602  sys::file_stat fs (name);
603 
604  if (fs.exists () && ! fs.is_dir ())
605  retval = name;
606  }
607  else if (len > 2 && name[len - 2] == '.' && name[len - 1] == 'm')
608  {
609  load_path& lp = __get_load_path__ ("fcn_file_in_path");
610 
611  retval = lp.find_fcn_file (name.substr (0, len-2));
612  }
613  else
614  {
615  std::string fname = name;
616  size_t pos = name.find_first_of ('>');
617  if (pos != std::string::npos)
618  fname = name.substr (0, pos);
619 
620  load_path& lp = __get_load_path__ ("fcn_file_in_path");
621 
622  retval = lp.find_fcn_file (fname);
623  }
624  }
625 
626  return retval;
627  }
628 
629  // See if there is a directory called "name" in the path and if it
630  // contains a Contents.m file. If so, return the full path to this file.
631 
632  std::string contents_file_in_path (const std::string& dir)
633  {
634  std::string retval;
635 
636  if (! dir.empty ())
637  {
638  load_path& lp = __get_load_path__ ("contents_in_file_path");
639 
640  std::string tcontents
641  = sys::file_ops::concat (lp.find_dir (dir), "Contents.m");
642 
643  sys::file_stat fs (tcontents);
644 
645  if (fs.exists ())
646  retval = sys::env::make_absolute (tcontents);
647  }
648 
649  return retval;
650  }
651 
652  // Replace backslash escapes in a string with the real values.
653 
654  std::string do_string_escapes (const std::string& s)
655  {
656  std::string retval;
657 
658  size_t i = 0;
659  size_t j = 0;
660  size_t len = s.length ();
661 
662  retval.resize (len);
663 
664  while (j < len)
665  {
666  if (s[j] == '\\' && j+1 < len)
667  {
668  switch (s[++j])
669  {
670  case 'a': // alarm
671  retval[i] = '\a';
672  break;
673 
674  case 'b': // backspace
675  retval[i] = '\b';
676  break;
677 
678  case 'f': // formfeed
679  retval[i] = '\f';
680  break;
681 
682  case 'n': // newline
683  retval[i] = '\n';
684  break;
685 
686  case 'r': // carriage return
687  retval[i] = '\r';
688  break;
689 
690  case 't': // horizontal tab
691  retval[i] = '\t';
692  break;
693 
694  case 'v': // vertical tab
695  retval[i] = '\v';
696  break;
697 
698  case '\\': // backslash
699  retval[i] = '\\';
700  break;
701 
702  case '\'': // quote
703  retval[i] = '\'';
704  break;
705 
706  case '"': // double quote
707  retval[i] = '"';
708  break;
709 
710  case '0':
711  case '1':
712  case '2':
713  case '3':
714  case '4':
715  case '5':
716  case '6':
717  case '7': // octal input
718  {
719  size_t k;
720  int tmpi = s[j] - '0';
721  for (k = j+1; k < std::min (j+3, len); k++)
722  {
723  int digit = s[k] - '0';
724  if (digit < 0 || digit > 7)
725  break;
726  tmpi <<= 3;
727  tmpi += digit;
728  }
729  retval[i] = tmpi;
730  j = k - 1;
731  break;
732  }
733 
734  case 'x': // hex input
735  {
736  size_t k;
737  int tmpi = 0;
738  for (k = j+1; k < std::min (j+3, len); k++)
739  {
740  if (! isxdigit (s[k]))
741  break;
742 
743  tmpi <<= 4;
744  int digit = s[k];
745  if (digit >= 'a')
746  tmpi += digit - 'a' + 10;
747  else if (digit >= 'A')
748  tmpi += digit - 'A' + 10;
749  else
750  tmpi += digit - '0';
751  }
752 
753  if (k == j+1)
754  warning (R"(malformed hex escape sequence '\x' -- converting to '\0')");
755 
756  retval[i] = tmpi;
757  j = k - 1;
758  break;
759  }
760 
761  default:
762  warning (R"(unrecognized escape sequence '\%c' -- converting to '%c')", s[j], s[j]);
763  retval[i] = s[j];
764  break;
765  }
766  }
767  else
768  retval[i] = s[j];
769 
770  i++;
771  j++;
772  }
773 
774  retval.resize (i);
775 
776  return retval;
777  }
778 }
779 
780 DEFUN (do_string_escapes, args, ,
781  doc: /* -*- texinfo -*-
782 @deftypefn {} {} do_string_escapes (@var{string})
783 Convert escape sequences in @var{string} to the characters they represent.
784 
785 Escape sequences begin with a leading backslash
786 (@qcode{'@xbackslashchar{}'}) followed by 1--3 characters
787 (.e.g., @qcode{"@xbackslashchar{}n"} => newline).
788 @seealso{undo_string_escapes}
789 @end deftypefn */)
790 {
791  if (args.length () != 1)
792  print_usage ();
793 
794  std::string str = args(0).xstring_value ("do_string_escapes: STRING argument must be of type string");
795 
796  return ovl (octave::do_string_escapes (str));
797 }
798 
799 /*
800 %!assert (do_string_escapes ('foo\nbar'), "foo\nbar")
801 %!assert (do_string_escapes ("foo\\nbar"), "foo\nbar")
802 %!assert (do_string_escapes ("foo\\nbar"), ["foo", char(10), "bar"])
803 %!assert ("foo\nbar", ["foo", char(10), "bar"])
804 
805 %!assert (do_string_escapes ('\0\a\b\f\n\r\t\v'), "\0\a\b\f\n\r\t\v")
806 %!assert (do_string_escapes ("\\0\\a\\b\\f\\n\\r\\t\\v"), "\0\a\b\f\n\r\t\v")
807 %!assert (do_string_escapes ("\\0\\a\\b\\f\\n\\r\\t\\v"),
808 %! char ([0, 7, 8, 12, 10, 13, 9, 11]))
809 %!assert ("\0\a\b\f\n\r\t\v", char ([0, 7, 8, 12, 10, 13, 9, 11]))
810 
811 %!assert (do_string_escapes ('\\'), "\\")
812 %!assert (do_string_escapes ("\\\\"), "\\")
813 %!assert (do_string_escapes ("\\\\"), char (92))
814 
815 %!assert (do_string_escapes ('\''single-quoted\'''), "'single-quoted'")
816 %!assert (do_string_escapes ("\\'single-quoted\\'"), "'single-quoted'")
817 %!assert (do_string_escapes ('\"double-quoted\"'), "\"double-quoted\"")
818 %!assert (do_string_escapes ("\\\"double-quoted\\\""), "\"double-quoted\"")
819 
820 %!assert (do_string_escapes ('A\4B'), ["A" char(4) "B"])
821 %!assert (do_string_escapes ('A\45B'), ["A" char(37) "B"])
822 %!assert (do_string_escapes ('A\123B'), ["A" char(83) "B"])
823 %!assert (sprintf ('\117\143\164\141\166\145'), "Octave")
824 
825 %!assert (do_string_escapes ('A\x4G'), ["A" char(4) "G"])
826 %!assert (do_string_escapes ('A\x4AG'), ["A" char(74) "G"])
827 %!assert (sprintf ('\x4f\x63\x74\x61\x76\x65'), "Octave")
828 
829 %!error do_string_escapes ()
830 %!error do_string_escapes ("foo", "bar")
831 %!error <STRING argument> do_string_escapes (3)
832 %!warning <malformed hex escape sequence> do_string_escapes ('\xG');
833 %!warning <unrecognized escape sequence> do_string_escapes ('\G');
834 */
835 
836 namespace octave
837 {
838  const char * undo_string_escape (char c)
839  {
840  if (! c)
841  return "";
842 
843  switch (c)
844  {
845  case '\0':
846  return R"(\0)";
847 
848  case '\a':
849  return R"(\a)";
850 
851  case '\b': // backspace
852  return R"(\b)";
853 
854  case '\f': // formfeed
855  return R"(\f)";
856 
857  case '\n': // newline
858  return R"(\n)";
859 
860  case '\r': // carriage return
861  return R"(\r)";
862 
863  case '\t': // horizontal tab
864  return R"(\t)";
865 
866  case '\v': // vertical tab
867  return R"(\v)";
868 
869  case '\\': // backslash
870  return R"(\\)";
871 
872  case '"': // double quote
873  return R"(\")";
874 
875  default:
876  {
877  static char retval[2] {'\0', '\0'};
878 
879  retval[0] = c;
880  return retval;
881  }
882  }
883  }
884 
885  std::string undo_string_escapes (const std::string& s)
886  {
887  std::string retval;
888 
889  for (size_t i = 0; i < s.length (); i++)
890  retval.append (undo_string_escape (s[i]));
891 
892  return retval;
893  }
894 }
895 
896 DEFUN (undo_string_escapes, args, ,
897  doc: /* -*- texinfo -*-
898 @deftypefn {} {} undo_string_escapes (@var{s})
899 Convert special characters in strings back to their escaped forms.
900 
901 For example, the expression
902 
903 @example
904 bell = "\a";
905 @end example
906 
907 @noindent
908 assigns the value of the alert character (control-g, ASCII code 7) to the
909 string variable @code{bell}. If this string is printed, the system will
910 ring the terminal bell (if it is possible). This is normally the desired
911 outcome. However, sometimes it is useful to be able to print the original
912 representation of the string, with the special characters replaced by their
913 escape sequences. For example,
914 
915 @example
916 @group
917 octave:13> undo_string_escapes (bell)
918 ans = \a
919 @end group
920 @end example
921 
922 @noindent
923 replaces the unprintable alert character with its printable representation.
924 @seealso{do_string_escapes}
925 @end deftypefn */)
926 {
927  if (args.length () != 1)
928  print_usage ();
929 
930  std::string str = args(0).xstring_value ("undo_string_escapes: S argument must be a string");
931 
932  return ovl (octave::undo_string_escapes (str));
933 }
934 
935 /*
936 %!assert (undo_string_escapes ("foo\nbar"), 'foo\nbar')
937 %!assert (undo_string_escapes ("foo\nbar"), "foo\\nbar")
938 %!assert (undo_string_escapes (["foo", char(10), "bar"]), "foo\\nbar")
939 
940 %!assert (undo_string_escapes ("\a\b\f\n\r\t\v"), '\a\b\f\n\r\t\v')
941 %!assert (undo_string_escapes ("\a\b\f\n\r\t\v"), "\\a\\b\\f\\n\\r\\t\\v")
942 %!assert (undo_string_escapes (char ([7, 8, 12, 10, 13, 9, 11])),
943 %! "\\a\\b\\f\\n\\r\\t\\v")
944 
945 %!assert (undo_string_escapes ("\\"), '\\')
946 %!assert (undo_string_escapes ("\\"), "\\\\")
947 %!assert (undo_string_escapes (char (92)), "\\\\")
948 
949 %!assert (undo_string_escapes ("\"double-quoted\""), '\"double-quoted\"')
950 %!assert (undo_string_escapes ("\"double-quoted\""), "\\\"double-quoted\\\"")
951 
952 %!error undo_string_escapes ()
953 %!error undo_string_escapes ("foo", "bar")
954 %!error undo_string_escapes (3)
955 */
956 
957 DEFUN (is_absolute_filename, args, ,
958  doc: /* -*- texinfo -*-
959 @deftypefn {} {} is_absolute_filename (@var{file})
960 Return true if @var{file} is an absolute filename.
961 @seealso{is_rooted_relative_filename, make_absolute_filename, isfolder}
962 @end deftypefn */)
963 {
964  if (args.length () != 1)
965  print_usage ();
966 
967  return ovl (args(0).is_string ()
968  && octave::sys::env::absolute_pathname (args(0).string_value ()));
969 }
970 
971 /*
972 ## FIXME: We need system-dependent tests here.
973 
974 %!error is_absolute_filename ()
975 %!error is_absolute_filename ("foo", "bar")
976 */
977 
978 DEFUN (is_rooted_relative_filename, args, ,
979  doc: /* -*- texinfo -*-
980 @deftypefn {} {} is_rooted_relative_filename (@var{file})
981 Return true if @var{file} is a rooted-relative filename.
982 @seealso{is_absolute_filename, make_absolute_filename, isfolder}
983 @end deftypefn */)
984 {
985  if (args.length () != 1)
986  print_usage ();
987 
988  return ovl (args(0).is_string ()
989  && octave::sys::env::rooted_relative_pathname (args(0).string_value ()));
990 }
991 
992 /*
993 ## FIXME: We need system-dependent tests here.
994 
995 %!error is_rooted_relative_filename ()
996 %!error is_rooted_relative_filename ("foo", "bar")
997 */
998 
999 DEFUN (make_absolute_filename, args, ,
1000  doc: /* -*- texinfo -*-
1001 @deftypefn {} {} make_absolute_filename (@var{file})
1002 Return the full name of @var{file} beginning from the root of the file
1003 system.
1004 
1005 No check is done for the existence of @var{file}. No tilde expansion of
1006 @var{file} is performed.
1007 @seealso{canonicalize_file_name, is_absolute_filename, is_rooted_relative_filename, isfolder, tilde_expand}
1008 @end deftypefn */)
1009 {
1010  if (args.length () != 1)
1011  print_usage ();
1012 
1013  std::string nm = args(0).xstring_value ("make_absolute_filename: FILE argument must be a filename");
1014 
1015  return ovl (octave::sys::env::make_absolute (nm));
1016 }
1017 
1018 /*
1019 ## FIXME: We need system-dependent tests here.
1020 
1021 %!error make_absolute_filename ()
1022 %!error make_absolute_filename ("foo", "bar")
1023 */
1024 
1025 DEFMETHOD (dir_in_loadpath, interp, args, ,
1026  doc: /* -*- texinfo -*-
1027 @deftypefn {} {@var{dirname} =} dir_in_loadpath (@var{dir})
1028 @deftypefnx {} {@var{dirname} =} dir_in_loadpath (@var{dir}, "all")
1029 Return the absolute name of the loadpath element matching @var{dir} if it can
1030 be found in the list of directories specified by @code{path}.
1031 
1032 If no match is found, return an empty character string.
1033 
1034 The match is performed at the end of each path element. For example, if
1035 @var{dir} is @qcode{"foo/bar"}, it matches the path element
1036 @nospell{@qcode{"/some/dir/foo/bar"}}, but not
1037 @nospell{@qcode{"/some/dir/foo/bar/baz"}}
1038 @nospell{@qcode{"/some/dir/allfoo/bar"}}. When @var{dir} is an absolute name,
1039 rather than just a path fragment, it is matched against the file system
1040 instead of Octave's loadpath. In this case, if @var{dir} exists it will be
1041 returned in @var{dirname}, otherwise an empty string is returned.
1042 
1043 If the optional second argument is supplied, return a cell array containing
1044 all name matches rather than just the first.
1045 @seealso{file_in_path, file_in_loadpath, path}
1046 @end deftypefn */)
1047 {
1048  int nargin = args.length ();
1049 
1050  if (nargin < 1 || nargin > 2)
1051  print_usage ();
1052 
1053  std::string dir;
1054 
1055  dir = args(0).xstring_value ("dir_in_loadpath: DIR must be a directory name");
1056 
1057  octave::load_path& lp = interp.get_load_path ();
1058 
1059  if (nargin == 1)
1060  return ovl (lp.find_dir (dir));
1061  else
1062  return ovl (Cell (lp.find_matching_dirs (dir)));
1063 }
1064 
1065 /*
1066 %!test
1067 %! f = dir_in_loadpath ("plot");
1068 %! assert (ischar (f));
1069 %! assert (! isempty (f));
1070 
1071 %!test
1072 %! f = dir_in_loadpath ("$$probably_!! _not_&&_a_!! _dir$$");
1073 %! assert (f, "");
1074 
1075 %!test
1076 %! lst = dir_in_loadpath ("$$probably_!! _not_&&_a_!! _dir$$", "all");
1077 %! assert (lst, {});
1078 
1079 %!error dir_in_loadpath ()
1080 %!error dir_in_loadpath ("foo", "bar", 1)
1081 */
1082 
1083 DEFUNX ("errno", Ferrno, args, ,
1084  doc: /* -*- texinfo -*-
1085 @deftypefn {} {@var{err} =} errno ()
1086 @deftypefnx {} {@var{err} =} errno (@var{val})
1087 @deftypefnx {} {@var{err} =} errno (@var{name})
1088 Query or set the system-dependent variable errno.
1089 
1090 When called with no inputs, return the current value of errno.
1091 
1092 When called with a numeric input @var{val}, set the current value of errno
1093 to the specified value. The previous value of errno is returned as @var{err}.
1094 
1095 When called with a character string @var{name}, return the numeric value of
1096 errno which corresponds to the specified error code. If @var{name} is not
1097 a recognized error code then -1 is returned.
1098 
1099 @seealso{errno_list}
1100 @end deftypefn */)
1101 {
1102  int nargin = args.length ();
1103 
1104  if (nargin > 1)
1105  print_usage ();
1106 
1108 
1109  if (nargin == 1)
1110  {
1111  if (args(0).is_string ())
1112  {
1113  std::string nm = args(0).string_value ();
1114 
1116  }
1117  else
1118  {
1119  int val = args(0).xint_value ("errno: argument must be string or integer");
1120 
1121  retval = octave_errno::set (val);
1122  }
1123  }
1124  else
1126 
1127  return retval;
1128 }
1129 
1130 /*
1131 %!assert (isnumeric (errno ()))
1132 
1133 %!test
1134 %! lst = errno_list ();
1135 %! fns = fieldnames (lst);
1136 %! oldval = errno (fns{1});
1137 %! assert (isnumeric (oldval));
1138 %! errno (oldval);
1139 %! newval = errno ();
1140 %! assert (oldval, newval);
1141 
1142 %!error errno ("foo", 1)
1143 */
1144 
1145 DEFUN (errno_list, args, ,
1146  doc: /* -*- texinfo -*-
1147 @deftypefn {} {} errno_list ()
1148 Return a structure containing the system-dependent errno values.
1149 @seealso{errno}
1150 @end deftypefn */)
1151 {
1152  if (args.length () != 0)
1153  print_usage ();
1154 
1155  return ovl (octave_errno::list ());
1156 }
1157 
1158 /*
1159 %!assert (isstruct (errno_list ()))
1160 
1161 %!error errno_list ("foo")
1162 */
1163 
1164 namespace octave
1165 {
1167  const char *warnfor)
1168  {
1169  if (nr < 0 || nc < 0)
1170  {
1171  warning_with_id ("Octave:neg-dim-as-zero",
1172  "%s: converting negative dimension to zero", warnfor);
1173 
1174  nr = (nr < 0) ? 0 : nr;
1175  nc = (nc < 0) ? 0 : nc;
1176  }
1177  }
1178 
1179  void check_dimensions (dim_vector& dim, const char *warnfor)
1180  {
1181  bool neg = false;
1182 
1183  for (int i = 0; i < dim.ndims (); i++)
1184  {
1185  if (dim(i) < 0)
1186  {
1187  dim(i) = 0;
1188  neg = true;
1189  }
1190  }
1191 
1192  if (neg)
1193  warning_with_id ("Octave:neg-dim-as-zero",
1194  "%s: converting negative dimension to zero", warnfor);
1195  }
1196 
1197  void get_dimensions (const octave_value& a, const char *warn_for,
1198  dim_vector& dim)
1199  {
1200  // We support dimensions to be specified by any vector, even if it's a
1201  // vector of dimensions 0x1, 1x0, 1x1x0, or 1x1x6. If the vector ends
1202  // up being empty, the final dimensions end up being 0x0.
1203  if (! a.dims ().isvector ())
1204  error ("%s (A): use %s (size (A)) instead", warn_for, warn_for);
1205 
1207  const octave_idx_type n = v.numel ();
1208 
1209  dim.resize (n); // even if n < 2, resize sets it back to 2
1210  if (n == 0)
1211  {
1212  dim(0) = 0;
1213  dim(1) = 0;
1214  }
1215  else if (n == 1)
1216  {
1217  dim(0) = v(0);
1218  dim(1) = v(0);
1219  }
1220  else
1221  for (octave_idx_type i = 0; i < n; i++)
1222  dim(i) = v(i);
1223 
1224  check_dimensions (dim, warn_for);
1225  }
1226 
1227  void get_dimensions (const octave_value& a, const char *warn_for,
1229  {
1230  if (a.is_scalar_type ())
1231  {
1232  nr = nc = a.idx_type_value (true);
1233  }
1234  else
1235  {
1236  nr = a.rows ();
1237  nc = a.columns ();
1238 
1239  if ((nr != 1 || nc != 2) && (nr != 2 || nc != 1))
1240  error ("%s (A): use %s (size (A)) instead", warn_for, warn_for);
1241 
1243  nr = v(0);
1244  nc = v(1);
1245  }
1246 
1247  check_dimensions (nr, nc, warn_for);
1248  }
1249 
1250  void get_dimensions (const octave_value& a, const octave_value& b,
1251  const char *warn_for, octave_idx_type& nr,
1252  octave_idx_type& nc)
1253  {
1254  nr = (a.isempty () ? 0 : a.idx_type_value (true));
1255  nc = (b.isempty () ? 0 : b.idx_type_value (true));
1256 
1257  check_dimensions (nr, nc, warn_for);
1258  }
1259 
1261  const octave_value_list& idx_arg)
1262  {
1264 
1265  octave_idx_type len = idx_arg.length ();
1266 
1267  if (len == 0)
1268  retval = dims.numel ();
1269  else
1270  {
1271  const dim_vector dv = dims.redim (len);
1272  retval = 1;
1273  for (octave_idx_type i = 0; i < len; i++)
1274  {
1275  octave_value idxi = idx_arg(i);
1276  if (idxi.is_magic_colon ())
1277  retval *= dv(i);
1278  else if (idxi.isnumeric ())
1279  retval *= idxi.numel ();
1280  else
1281  {
1282  try
1283  {
1284  idx_vector jdx = idxi.index_vector ();
1285 
1286  retval *= jdx.length (dv(i));
1287  }
1288  catch (const index_exception& e)
1289  {
1290  error ("dims_to_numel: invalid index %s", e.what ());
1291  }
1292  }
1293  }
1294  }
1295 
1296  return retval;
1297  }
1298 
1300  {
1301  Matrix m (nr, nc, 0.0);
1302 
1303  if (nr > 0 && nc > 0)
1304  {
1305  octave_idx_type n = std::min (nr, nc);
1306 
1307  for (octave_idx_type i = 0; i < n; i++)
1308  m (i, i) = 1.0;
1309  }
1310 
1311  return m;
1312  }
1313 
1315  {
1316  FloatMatrix m (nr, nc, 0.0);
1317 
1318  if (nr > 0 && nc > 0)
1319  {
1320  octave_idx_type n = std::min (nr, nc);
1321 
1322  for (octave_idx_type i = 0; i < n; i++)
1323  m (i, i) = 1.0;
1324  }
1325 
1326  return m;
1327  }
1328 
1329  size_t format (std::ostream& os, const char *fmt, ...)
1330  {
1331  size_t retval;
1332 
1333  va_list args;
1334  va_start (args, fmt);
1335 
1336  retval = vformat (os, fmt, args);
1337 
1338  va_end (args);
1339 
1340  return retval;
1341  }
1342 
1343  size_t vformat (std::ostream& os, const char *fmt, va_list args)
1344  {
1345  std::string s = vasprintf (fmt, args);
1346 
1347  os << s;
1348 
1349  return s.length ();
1350  }
1351 
1352  size_t format (std::ostream& os, const std::string& enc, const char *fmt, ...)
1353  {
1354  size_t retval;
1355 
1356  va_list args;
1357  va_start (args, fmt);
1358 
1359  retval = vformat (os, enc, fmt, args);
1360 
1361  va_end (args);
1362 
1363  return retval;
1364  }
1365 
1366  size_t vformat (std::ostream& os, const std::string& enc, const char *fmt,
1367  va_list args)
1368  {
1369  std::string s = vasprintf (fmt, args);
1370 
1371  if (enc.compare ("utf-8"))
1372  os << string::u8_to_encoding ("printf", s, enc);
1373  else
1374  os << s;
1375 
1376  return s.length ();
1377  }
1378 
1379  std::string vasprintf (const char *fmt, va_list args)
1380  {
1381  std::string retval;
1382 
1383  char *result;
1384 
1385  int status = octave_vasprintf_wrapper (&result, fmt, args);
1386 
1387  if (status >= 0)
1388  {
1389  retval = result;
1390  ::free (result);
1391  }
1392 
1393  return retval;
1394  }
1395 
1396  std::string asprintf (const char *fmt, ...)
1397  {
1398  std::string retval;
1399 
1400  va_list args;
1401  va_start (args, fmt);
1402 
1403  retval = vasprintf (fmt, args);
1404 
1405  va_end (args);
1406 
1407  return retval;
1408  }
1409 
1410  // FIXME: sleep is complicated because we want it to be interruptible.
1411  // With the way this program handles signals, the sleep system call
1412  // won't respond to SIGINT. Maybe there is a better way than
1413  // breaking this up into multiple shorter intervals?
1414 
1415  void sleep (double seconds, bool do_graphics_events)
1416  {
1417  if (seconds <= 0)
1418  return;
1419 
1420  // Allow free access to graphics resources while the interpreter thread
1421  // is asleep
1422 
1423  gh_manager& gh_mgr = __get_gh_manager__ ("sleep");
1424 
1425  if (do_graphics_events)
1426  gh_mgr.unlock ();
1427 
1428  if (math::isinf (seconds))
1429  {
1430  // Wait for kbhit
1431  int c = -1;
1432  flush_stdout ();
1433 
1434  struct timespec one_tenth = { 0, 100000000 };
1435 
1436  while (c < 0)
1437  {
1438  octave_nanosleep_wrapper (&one_tenth, nullptr);
1439 
1440  octave_quit ();
1441 
1442  if (do_graphics_events)
1443  gh_mgr.process_events ();
1444 
1445  c = kbhit (false);
1446  }
1447  }
1448  else
1449  {
1450  sys::time now;
1451  double end_time = now.double_value () + seconds;
1452  double remaining_time = seconds;
1453 
1454  // Split pause into 100 ms time steps to allow the execution of
1455  // graphics events and interrupts.
1456  struct timespec nano_laps = { 0, 100000000 };
1457 
1458  while (remaining_time > 0.1)
1459  {
1460  octave_quit ();
1461 
1462  if (do_graphics_events)
1463  {
1464  gh_mgr.process_events ();
1465 
1466  now.stamp ();
1467  remaining_time = end_time - now.double_value ();
1468 
1469  if (remaining_time < 0.1)
1470  break;
1471  }
1472 
1473  octave_nanosleep_wrapper (&nano_laps, nullptr);
1474 
1475  now.stamp ();
1476  remaining_time = end_time - now.double_value ();
1477  }
1478 
1479  if (remaining_time > 0.0)
1480  {
1481  nano_laps = { 0, static_cast<int> (remaining_time * 1e9) };
1482  octave_nanosleep_wrapper (&nano_laps, nullptr);
1483  }
1484  }
1485  }
1486 }
1487 
1488 DEFMETHOD (isindex, interp, args, ,
1489  doc: /* -*- texinfo -*-
1490 @deftypefn {} {} isindex (@var{ind})
1491 @deftypefnx {} {} isindex (@var{ind}, @var{n})
1492 Return true if @var{ind} is a valid index.
1493 
1494 Valid indices are either positive integers (although possibly of real data
1495 type), or logical arrays.
1496 
1497 If present, @var{n} specifies the maximum extent of the dimension to be
1498 indexed. When possible the internal result is cached so that subsequent
1499 indexing using @var{ind} will not perform the check again.
1500 
1501 Implementation Note: Strings are first converted to double values before the
1502 checks for valid indices are made. Unless a string contains the NULL
1503 character @nospell{"@xbackslashchar{}0"}, it will always be a valid index.
1504 @end deftypefn */)
1505 {
1506  int nargin = args.length ();
1507 
1508  if (nargin < 1 || nargin > 2)
1509  print_usage ();
1510 
1511  octave_idx_type n = 0;
1512  if (nargin == 2)
1513  n = args(1).idx_type_value ();
1514 
1516 
1517  try
1518  {
1519  idx_vector idx = args(0).index_vector (true);
1520 
1521  if (nargin == 2)
1522  retval = idx.extent (n) <= n;
1523  else
1524  retval = true;
1525  }
1526  catch (const octave::execution_exception&)
1527  {
1528  interp.recover_from_exception ();
1529 
1530  retval = false;
1531  }
1532 
1533  return retval;
1534 }
1535 
1536 /*
1537 %!assert (isindex ([1, 2, 3]))
1538 %!assert (isindex (1:3))
1539 %!assert (isindex (1:3, 2), false)
1540 %!assert (isindex ([1, 2, -3]), false)
1541 
1542 %!error isindex ()
1543 %!error isindex (1:3, 2, 3)
1544 */
1545 
1546 namespace octave
1547 {
1550  const char *fun_name, const octave_value_list& args,
1551  int nargout)
1552  {
1553  octave_value_list new_args = args;
1555  int nargin = args.length ();
1556  OCTAVE_LOCAL_BUFFER (bool, iscell, nargin);
1557  OCTAVE_LOCAL_BUFFER (Cell, cells, nargin);
1558  OCTAVE_LOCAL_BUFFER (Cell, rcells, nargout);
1559 
1560  const Cell *ccells = cells;
1561 
1562  octave_idx_type numel = 1;
1563  dim_vector dims (1, 1);
1564 
1565  for (int i = 0; i < nargin; i++)
1566  {
1567  octave_value arg = new_args(i);
1568  iscell[i] = arg.iscell ();
1569  if (iscell[i])
1570  {
1571  cells[i] = arg.cell_value ();
1572  octave_idx_type n = ccells[i].numel ();
1573  if (n == 1)
1574  {
1575  iscell[i] = false;
1576  new_args(i) = ccells[i](0);
1577  }
1578  else if (numel == 1)
1579  {
1580  numel = n;
1581  dims = ccells[i].dims ();
1582  }
1583  else if (dims != ccells[i].dims ())
1584  error ("%s: cell arguments must have matching sizes", fun_name);
1585  }
1586  }
1587 
1588  for (int i = 0; i < nargout; i++)
1589  rcells[i].clear (dims);
1590 
1591  for (octave_idx_type j = 0; j < numel; j++)
1592  {
1593  for (int i = 0; i < nargin; i++)
1594  if (iscell[i])
1595  new_args(i) = ccells[i](j);
1596 
1597  octave_quit ();
1598 
1599  const octave_value_list tmp = fun (new_args, nargout);
1600 
1601  if (tmp.length () < nargout)
1602  error ("%s: do_simple_cellfun: internal error", fun_name);
1603 
1604  for (int i = 0; i < nargout; i++)
1605  rcells[i](j) = tmp(i);
1606  }
1607 
1608  retval.resize (nargout);
1609 
1610  for (int i = 0; i < nargout; i++)
1611  retval(i) = rcells[i];
1612 
1613  return retval;
1614  }
1615 
1616  octave_value
1618  const char *fun_name, const octave_value_list& args)
1619  {
1621 
1622  const octave_value_list tmp = do_simple_cellfun (fun, fun_name, args, 1);
1623 
1624  if (tmp.length () > 0)
1625  retval = tmp(0);
1626 
1627  return retval;
1628  }
1629 }
1630 
1631 DEFUN (isstudent, args, ,
1632  doc: /* -*- texinfo -*-
1633 @deftypefn {} {} isstudent ()
1634 Return true if running in the student edition of @sc{matlab}.
1635 
1636 @code{isstudent} always returns false in Octave.
1637 @seealso{false}
1638 @end deftypefn */)
1639 {
1640  if (args.length () != 0)
1641  print_usage ();
1642 
1643  return ovl (false);
1644 }
1645 
1646 /*
1647 %!assert (isstudent (), false)
1648 
1649 %!error isstudent (1)
1650 */
1651 
1652 // Always define these functions. The macro is intended to allow the
1653 // declarations to be hidden, not so that Octave will not provide the
1654 // functions if they are requested.
1655 
1656 // #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
1657 
1658 #include "ov.h"
1659 #include "ovl.h"
1660 #include "str-vec.h"
1661 
1662 bool
1663 valid_identifier (const char *s)
1664 {
1665  return octave::valid_identifier (s);
1666 }
1667 
1668 bool
1669 valid_identifier (const std::string& s)
1670 {
1671  return octave::valid_identifier (s);
1672 }
1673 
1674 bool
1675 same_file (const std::string& f, const std::string& g)
1676 {
1677  return octave::same_file (f, g);
1678 }
1679 
1680 int
1681 almost_match (const std::string& std, const std::string& s,
1682  int min_match_len, int case_sens)
1683 {
1684  return octave::almost_match (std, s, min_match_len, case_sens);
1685 }
1686 
1687 int
1688 keyword_almost_match (const char * const *std, int *min_len,
1689  const std::string& s, int min_toks_to_match,
1690  int max_toks)
1691 {
1692  return octave::keyword_almost_match (std, min_len, s, min_toks_to_match,
1693  max_toks);
1694 }
1695 
1696 std::string
1697 search_path_for_file (const std::string& path, const string_vector& names)
1698 {
1699  return octave::search_path_for_file (path, names);
1700 }
1701 
1703 search_path_for_all_files (const std::string& path, const string_vector& names)
1704 {
1705  return octave::search_path_for_all_files (path, names);
1706 }
1707 
1708 std::string
1709 file_in_path (const std::string& name, const std::string& suffix)
1710 {
1711  return octave::file_in_path (name, suffix);
1712 }
1713 
1714 std::string
1715 find_data_file_in_load_path (const std::string& fcn, const std::string& file,
1716  bool require_regular_file)
1717 {
1718  return octave::find_data_file_in_load_path (fcn, file, require_regular_file);
1719 }
1720 
1721 std::string
1722 contents_file_in_path (const std::string& s)
1723 {
1724  return octave::contents_file_in_path (s);
1725 }
1726 
1727 std::string
1728 fcn_file_in_path (const std::string& s)
1729 {
1730  return octave::fcn_file_in_path (s);
1731 }
1732 
1733 std::string
1734 do_string_escapes (const std::string& s)
1735 {
1736  return octave::do_string_escapes (s);
1737 }
1738 
1739 const char *
1741 {
1742  return octave::undo_string_escape (c);
1743 }
1744 
1745 std::string
1746 undo_string_escapes (const std::string& s)
1747 {
1748  return octave::undo_string_escapes (s);
1749 }
1750 
1751 void
1752 check_dimensions (dim_vector& dim, const char *warnfor)
1753 {
1754  return octave::check_dimensions (dim, warnfor);
1755 }
1756 
1757 void
1758 get_dimensions (const octave_value& a, const char *warn_for,
1759  dim_vector& dim)
1760 {
1761  return octave::get_dimensions (a, warn_for, dim);
1762 }
1763 
1764 void
1766  const char *warn_for, octave_idx_type& nr,
1767  octave_idx_type& nc)
1768 {
1769  return octave::get_dimensions (a, b, warn_for, nr, nc);
1770 }
1771 
1772 void
1773 get_dimensions (const octave_value& a, const char *warn_for,
1775 {
1776  return octave::get_dimensions (a, warn_for, nr, nc);
1777 }
1778 
1780 dims_to_numel (const dim_vector& dims, const octave_value_list& idx)
1781 {
1782  return octave::dims_to_numel (dims, idx);
1783 }
1784 
1785 Matrix
1787 {
1788  return octave::identity_matrix (nr, nc);
1789 }
1790 
1793 {
1794  return octave::float_identity_matrix (nr, nc);
1795 }
1796 
1797 size_t
1798 octave_vformat (std::ostream& os, const char *fmt, va_list args)
1799 {
1800  return octave::vformat (os, fmt, args);
1801 }
1802 
1803 std::string
1804 octave_vasprintf (const char *fmt, va_list args)
1805 {
1806  return octave::vasprintf (fmt, args);
1807 }
1808 
1809 void
1810 octave_sleep (double seconds)
1811 {
1812  octave::sleep (seconds);
1813 }
1814 
1817  const char *fun_name, const octave_value_list& args,
1818  int nargout)
1819 {
1820  return octave::do_simple_cellfun (fun, fun_name, args, nargout);
1821 }
1822 
1825  const char *fun_name, const octave_value_list& args)
1826 {
1827  return octave::do_simple_cellfun (fun, fun_name, args);
1828 }
1829 
1830 // #endif
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1011
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:453
Definition: Cell.h:43
Definition: dMatrix.h:42
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:401
void resize(int n, int fill_value=0)
Definition: dim-vector.h:349
bool isvector(void) const
Definition: dim-vector.h:461
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:334
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:245
void unlock(void)
Definition: graphics.in.h:6320
int process_events(bool force=false)
Definition: graphics.cc:12268
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:558
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:561
std::string find_first_of(const std::list< std::string > &names)
Definition: pathsearch.cc:86
std::list< std::string > find_all_first_of(const std::list< std::string > &names)
Definition: pathsearch.cc:93
std::string find_first_of(const string_vector &files) const
Definition: load-path.cc:687
std::string find_fcn_file(const std::string &fcn, const std::string &pack_name="")
Definition: load-path.h:131
string_vector find_all_first_of(const string_vector &files) const
Definition: load-path.cc:764
string_vector find_matching_dirs(const std::string &dir) const
Definition: load-path.cc:640
std::string find_dir(const std::string &dir) const
Definition: load-path.cc:593
std::string find_file(const std::string &file) const
Definition: load-path.cc:538
bool is_reg(void) const
Definition: file-stat.cc:83
bool is_dir(void) const
Definition: file-stat.cc:65
bool exists(void) const
Definition: file-stat.h:147
static bool rooted_relative_pathname(const std::string &s)
Definition: oct-env.cc:119
static bool absolute_pathname(const std::string &s)
Definition: oct-env.cc:112
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:133
double double_value(void) const
Definition: oct-time.h:108
void stamp(void)
Definition: oct-time.cc:109
static int set(int val)
Definition: oct-errno.h:58
static int lookup(const std::string &name)
static octave_scalar_map list(void)
static int get(void)
Definition: oct-errno.h:56
octave_idx_type length(void) const
Definition: ovl.h:113
bool iscell(void) const
Definition: ov.h:560
octave_idx_type rows(void) const
Definition: ov.h:504
bool isnumeric(void) const
Definition: ov.h:703
octave_idx_type numel(void) const
Definition: ov.h:518
octave_idx_type idx_type_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type(void) const
Definition: ov.h:697
Cell cell_value(void) const
octave_idx_type columns(void) const
Definition: ov.h:506
Array< octave_idx_type > octave_idx_type_vector_value(bool req_int=false, bool frc_str_conv=false, bool frc_vec_conv=false) const
std::string string_value(bool force=false) const
Definition: ov.h:927
bool isempty(void) const
Definition: ov.h:557
idx_vector index_vector(bool require_integers=false) const
Definition: ov.h:493
Array< std::string > cellstr_value(void) const
Definition: ov.h:935
bool is_magic_colon(void) const
Definition: ov.h:629
dim_vector dims(void) const
Definition: ov.h:500
octave_idx_type numel(void) const
Definition: str-vec.h:100
bool empty(void) const
Definition: str-vec.h:77
std::list< std::string > std_list(void) const
Definition: str-vec.cc:172
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFUNX(name, fname, args_name, nargout_name, doc)
Macro to define a builtin function with certain internal name.
Definition: defun.h:85
void warning(const char *fmt,...)
Definition: error.cc:1050
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1065
void error(const char *fmt,...)
Definition: error.cc:968
void warn_data_file_in_path(const std::string &fcn, const std::string &file)
Definition: errwarn.cc:310
QString path
QString name
OCTAVE_API int octave_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: lo-cutils.c:49
F77_RET_T const F77_DBLE const F77_DBLE * f
static char * strsave(const char *s)
Definition: main.in.cc:195
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
bool isinf(double x)
Definition: lo-mappers.h:203
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:156
OCTAVE_API std::string u8_to_encoding(const std::string &who, const std::string &u8_string, const std::string &encoding)
Definition: oct-string.cc:495
std::string concat(const std::string &dir, const std::string &file)
Definition: file-ops.cc:354
gh_manager & __get_gh_manager__(const std::string &who)
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
Definition: utils.cc:1197
int almost_match(const std::string &std, const std::string &s, int min_match_len, int case_sens)
Definition: utils.cc:257
std::string vasprintf(const char *fmt, va_list args)
Definition: utils.cc:1379
std::string contents_file_in_path(const std::string &dir)
Definition: utils.cc:632
bool valid_identifier(const char *s)
Definition: utils.cc:77
static void check_dimensions(octave_idx_type &nr, octave_idx_type &nc, const char *warnfor)
Definition: utils.cc:1166
static double f(double k, double l_nu, double c_pm)
Definition: randpoisson.cc:118
void flush_stdout(void)
Definition: pager.cc:260
std::string do_string_escapes(const std::string &s)
Definition: utils.cc:654
bool same_file_internal(const std::string &file1, const std::string &file2)
Definition: sysdep.cc:309
bool iskeyword(const std::string &s)
Definition: lex.cc:1283
int kbhit(bool wait)
Definition: sysdep.cc:654
string_vector search_path_for_all_files(const std::string &path, const string_vector &names)
Definition: utils.cc:370
const char * undo_string_escape(char c)
Definition: utils.cc:838
std::string asprintf(const char *fmt,...)
Definition: utils.cc:1396
void sleep(double seconds, bool do_graphics_events)
Definition: utils.cc:1415
octave_value_list do_simple_cellfun(octave_value_list(*fun)(const octave_value_list &, int), const char *fun_name, const octave_value_list &args, int nargout)
Definition: utils.cc:1549
Matrix identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1299
std::string fcn_file_in_path(const std::string &name)
Definition: utils.cc:592
int keyword_almost_match(const char *const *std, int *min_len, const std::string &s, int min_toks_to_match, int max_toks)
Definition: utils.cc:272
size_t vformat(std::ostream &os, const char *fmt, va_list args)
Definition: utils.cc:1343
std::string file_in_path(const std::string &name, const std::string &suffix)
Definition: utils.cc:541
std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file)
Definition: utils.cc:553
size_t format(std::ostream &os, const char *fmt,...)
Definition: utils.cc:1329
FloatMatrix float_identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1314
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:138
std::string search_path_for_file(const std::string &path, const string_vector &names)
Definition: utils.cc:360
std::string undo_string_escapes(const std::string &s)
Definition: utils.cc:885
octave_idx_type dims_to_numel(const dim_vector &dims, const octave_value_list &idx_arg)
Definition: utils.cc:1260
load_path & __get_load_path__(const std::string &who)
static string_vector make_absolute(const string_vector &sv)
Definition: utils.cc:385
int octave_nanosleep_wrapper(const struct timespec *requested, struct timespec *remaining)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
T::size_type numel(const T &str)
Definition: oct-string.cc:71
void free(void *)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
std::string do_string_escapes(const std::string &s)
Definition: utils.cc:1734
std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file)
Definition: utils.cc:1715
octave_idx_type dims_to_numel(const dim_vector &dims, const octave_value_list &idx)
Definition: utils.cc:1780
std::string undo_string_escapes(const std::string &s)
Definition: utils.cc:1746
int almost_match(const std::string &std, const std::string &s, int min_match_len, int case_sens)
Definition: utils.cc:1681
int keyword_almost_match(const char *const *std, int *min_len, const std::string &s, int min_toks_to_match, int max_toks)
Definition: utils.cc:1688
Matrix identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1786
std::string file_in_path(const std::string &name, const std::string &suffix)
Definition: utils.cc:1709
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
Definition: utils.cc:1758
bool valid_identifier(const char *s)
Definition: utils.cc:1663
octave_value_list do_simple_cellfun(octave_value_list(*fun)(const octave_value_list &, int), const char *fun_name, const octave_value_list &args, int nargout)
Definition: utils.cc:1816
FloatMatrix float_identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1792
void octave_sleep(double seconds)
Definition: utils.cc:1810
OCTAVE_EXPORT octave_value_list Ferrno(const octave_value_list &args, int)
Definition: utils.cc:1100
string_vector search_path_for_all_files(const std::string &path, const string_vector &names)
Definition: utils.cc:1703
std::string contents_file_in_path(const std::string &s)
Definition: utils.cc:1722
size_t octave_vformat(std::ostream &os, const char *fmt, va_list args)
Definition: utils.cc:1798
std::string fcn_file_in_path(const std::string &s)
Definition: utils.cc:1728
const char * undo_string_escape(char c)
Definition: utils.cc:1740
std::string search_path_for_file(const std::string &path, const string_vector &names)
Definition: utils.cc:1697
void check_dimensions(dim_vector &dim, const char *warnfor)
Definition: utils.cc:1752
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:1675
std::string octave_vasprintf(const char *fmt, va_list args)
Definition: utils.cc:1804
int octave_vasprintf_wrapper(char **buf, const char *fmt, va_list args)
F77_RET_T len
Definition: xerbla.cc:61