GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
sysdep.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 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 <cmath>
31 #include <cstddef>
32 
33 #include <iostream>
34 #include <string>
35 
36 #if defined (HAVE_TERMIOS_H)
37 # include <termios.h>
38 #elif defined (HAVE_TERMIO_H)
39 # include <termio.h>
40 #elif defined (HAVE_SGTTY_H)
41 # include <sgtty.h>
42 #endif
43 
44 #if defined (HAVE_CONIO_H)
45 # include <conio.h>
46 #endif
47 
48 #if defined (HAVE_SYS_IOCTL_H)
49 # include <sys/ioctl.h>
50 #endif
51 
52 #if defined (HAVE_FLOATINGPOINT_H)
53 # include <floatingpoint.h>
54 #endif
55 
56 #if defined (HAVE_IEEEFP_H)
57 # include <ieeefp.h>
58 #endif
59 
60 #if defined (HAVE_OMP_H)
61 # include <omp.h>
62 #endif
63 
64 #include "cmd-edit.h"
65 #include "file-ops.h"
66 #include "lo-mappers.h"
67 #include "lo-sysinfo.h"
68 #include "mach-info.h"
69 #include "oct-env.h"
70 #include "uniconv-wrappers.h"
71 #include "unistd-wrappers.h"
72 
73 #include "builtin-defun-decls.h"
74 #include "Cell.h"
75 #include "defun.h"
76 #include "error.h"
77 #include "errwarn.h"
78 #include "input.h"
79 #include "interpreter-private.h"
80 #include "octave.h"
81 #include "ov.h"
82 #include "ovl.h"
83 #include "pager.h"
84 #include "parse.h"
85 #include "sighandlers.h"
86 #include "sysdep.h"
87 #include "interpreter.h"
88 #include "utils.h"
89 #include "file-stat.h"
90 
91 #if ! defined (STDIN_FILENO)
92 # define STDIN_FILENO 1
93 #endif
94 
95 #if defined (__MINGW32__) || defined (_MSC_VER)
96 
97 #define WIN32_LEAN_AND_MEAN
98 #include <windows.h>
99 #include <tlhelp32.h>
100 #include <psapi.h>
101 #include <shellapi.h>
102 #include <shobjidl.h>
103 
104 #endif
105 
107 
108 #if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
109 
110 static void
111 BSD_init ()
112 {
113 # if defined (HAVE_FLOATINGPOINT_H)
114  // Disable trapping on common exceptions.
115 # if ! defined (FP_X_DNML)
116 # define FP_X_DNML 0
117 # endif
118  fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
119 # endif
120 }
121 
122 #endif
123 
124 #if defined (__MINGW32__) || defined (_MSC_VER)
125 
126 static void
127 w32_set_octave_home ()
128 {
129  std::string bin_dir;
130 
131  HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE
132 #if defined (TH32CS_SNAPMODULE32)
133  | TH32CS_SNAPMODULE32
134 #endif
135  , 0);
136 
137  if (h != INVALID_HANDLE_VALUE)
138  {
139  MODULEENTRY32W mod_info;
140 
141  ZeroMemory (&mod_info, sizeof (mod_info));
142  mod_info.dwSize = sizeof (mod_info);
143 
144  if (Module32FirstW (h, &mod_info))
145  {
146  do
147  {
148  std::string mod_name (sys::u8_from_wstring (mod_info.szModule));
149 
150  if (mod_name.find ("octinterp") != std::string::npos)
151  {
152  bin_dir = sys::u8_from_wstring (mod_info.szExePath);
153  if (! bin_dir.empty () && bin_dir.back () != '\\')
154  bin_dir.push_back ('\\');
155  break;
156  }
157  }
158  while (Module32NextW (h, &mod_info));
159  }
160 
161  CloseHandle (h);
162  }
163 
164  if (! bin_dir.empty ())
165  {
166  std::size_t pos = bin_dir.rfind (R"(\bin\)");
167 
168  if (pos != std::string::npos)
169  sys::env::putenv ("OCTAVE_HOME", bin_dir.substr (0, pos));
170  }
171 }
172 
173 static void
174 w32_init ()
175 {
176  w32_set_octave_home ();
177 
179 }
180 
181 #endif
182 
183 void
185 {
186 #if defined (__MINGW32__) || defined (_MSC_VER)
187 
188  SetCurrentProcessExplicitAppUserModelID (L"gnu.octave." VERSION);
189 
190 #endif
191 }
192 
193 DEFUN (__open_with_system_app__, args, ,
194  doc: /* -*- texinfo -*-
195 @deftypefn {} {@var{status} =} __open_with_system_app__ (@var{file})
196 Return 1 on successful system call and 0 otherwise.
197 @end deftypefn */)
198 {
199  if (args.length () != 1)
200  print_usage ();
201 
202  std::string file = args(0).xstring_value ("__open_with_system_app__: argument must be a filename");
203 
204 #if defined (OCTAVE_USE_WINDOWS_API)
205  std::wstring wfile = sys::u8_to_wstring (file);
206  HINSTANCE status = ShellExecuteW (0, 0, wfile.c_str (), 0, 0, SW_SHOWNORMAL);
207 
208  // ShellExecute returns a value greater than 32 if successful.
209  return octave_value (reinterpret_cast<std::ptrdiff_t> (status) > 32);
210 #else
211  // Quote file path
212  file = '"' + file + '"';
213 
214 # if defined (__APPLE__)
215 # define FSYSTEM_OPEN_STR "open "
216 # else
217 # define FSYSTEM_OPEN_STR "xdg-open "
218 # endif
220  = Fsystem (ovl (FSYSTEM_OPEN_STR + file + " 2> /dev/null",
221  false, "async"),
222  1);
223 # undef FSYSTEM_OPEN_STR
224 
225  // Asynchronous Fsystem calls return the new child process identifier,
226  // which must be greater than 1 if successful.
227  return octave_value (tmp(0).double_value () > 1);
228 #endif
229 }
230 
231 DEFUN (__is_elevated_process__, args, ,
232  doc: /* -*- texinfo -*-
233 @deftypefn {} {@var{retval} =} __is_elevated_process__ ()
234 Check if current process has elevated rights.
235 
236 On Windows, return true if the current process has elevated right. Otherwise,
237 return false.
238 On non-Windows platforms, this function fails with an error.
239 @end deftypefn */)
240 {
241 #if defined (OCTAVE_USE_WINDOWS_API)
242  if (args.length () != 0)
243  print_usage ();
244 
245  bool retval = false;
246  HANDLE h_token = nullptr;
247 
248  if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &h_token))
249  {
250  TOKEN_ELEVATION elevation;
251  DWORD return_length = sizeof (TOKEN_ELEVATION);
252  if (GetTokenInformation (h_token, TokenElevation, &elevation,
253  sizeof (elevation), &return_length))
254  retval = elevation.TokenIsElevated;
255  }
256 
257  if (h_token)
258  CloseHandle (h_token);
259 
260  return ovl (retval);
261 
262 #else
263  octave_unused_parameter (args);
264  error ("__is_elevated_process__: "
265  "Function is only supported on Windows platforms.");
266 #endif
267 }
268 
269 DEFUN (__wmemory__, args, ,
270  doc: /* -*- texinfo -*-
271 @deftypefn {} {[@var{proc}, @var{sys}] =} __wmemory__ ()
272 Return memory information on Windows.
273 
274 On non-Windows platforms, this function fails with an error.
275 @end deftypefn */)
276 {
277 #if defined (OCTAVE_USE_WINDOWS_API)
278  if (args.length () != 0)
279  print_usage ();
280 
281  // Get memory usage of the current process
282  octave_scalar_map proc_struct;
283 
284  HANDLE h_proc = GetCurrentProcess ();
285  if (h_proc == nullptr)
286  error ("__wmemory__: Couldn't open handle to own process");
287 
288  PROCESS_MEMORY_COUNTERS proc_mem_count;
289  if (GetProcessMemoryInfo (h_proc, &proc_mem_count, sizeof (proc_mem_count)))
290  {
291  proc_struct.setfield ("PageFaultCount",
292  proc_mem_count.PageFaultCount);
293  proc_struct.setfield ("PeakWorkingSetSize",
294  proc_mem_count.PeakWorkingSetSize);
295  proc_struct.setfield ("WorkingSetSize",
296  proc_mem_count.WorkingSetSize);
297  proc_struct.setfield ("QuotaPeakPagedPoolUsage",
298  proc_mem_count.QuotaPeakPagedPoolUsage);
299  proc_struct.setfield ("QuotaPagedPoolUsage",
300  proc_mem_count.QuotaPagedPoolUsage);
301  proc_struct.setfield ("QuotaPeakNonPagedPoolUsage",
302  proc_mem_count.QuotaPeakNonPagedPoolUsage);
303  proc_struct.setfield ("QuotaNonPagedPoolUsage",
304  proc_mem_count.QuotaNonPagedPoolUsage);
305  proc_struct.setfield ("PagefileUsage",
306  proc_mem_count.PagefileUsage);
307  proc_struct.setfield ("PeakPagefileUsage",
308  proc_mem_count.PeakPagefileUsage);
309  }
310  else
311  {
312  proc_struct.setfield ("PageFaultCount", 0);
313  proc_struct.setfield ("PeakWorkingSetSize", 0);
314  proc_struct.setfield ("WorkingSetSize", 0);
315  proc_struct.setfield ("QuotaPeakPagedPoolUsage", 0);
316  proc_struct.setfield ("QuotaPagedPoolUsage", 0);
317  proc_struct.setfield ("QuotaPeakNonPagedPoolUsage", 0);
318  proc_struct.setfield ("QuotaNonPagedPoolUsage", 0);
319  proc_struct.setfield ("PagefileUsage", 0);
320  proc_struct.setfield ("PeakPagefileUsage", 0);
321  }
322 
323  CloseHandle (h_proc);
324 
325  // Get system memory usage
326  octave_scalar_map sys_struct;
327 
328  MEMORYSTATUSEX mem_stat;
329 
330  mem_stat.dwLength = sizeof (mem_stat);
331 
332  if (GlobalMemoryStatusEx (&mem_stat))
333  {
334  sys_struct.setfield ("MemoryLoad", mem_stat.dwMemoryLoad);
335  sys_struct.setfield ("TotalPhys", mem_stat.ullTotalPhys);
336  sys_struct.setfield ("AvailPhys", mem_stat.ullAvailPhys);
337  sys_struct.setfield ("TotalPageFile", mem_stat.ullTotalPageFile);
338  sys_struct.setfield ("AvailPageFile", mem_stat.ullAvailPageFile);
339  sys_struct.setfield ("TotalVirtual", mem_stat.ullTotalVirtual);
340  sys_struct.setfield ("AvailVirtual", mem_stat.ullAvailVirtual);
341  sys_struct.setfield ("AvailExtendedVirtual",
342  mem_stat.ullAvailExtendedVirtual);
343  }
344  else
345  {
346  sys_struct.setfield ("MemoryLoad", 0);
347  sys_struct.setfield ("TotalPhys", 0);
348  sys_struct.setfield ("AvailPhys", 0);
349  sys_struct.setfield ("TotalPageFile", 0);
350  sys_struct.setfield ("AvailPageFile", 0);
351  sys_struct.setfield ("TotalVirtual", 0);
352  sys_struct.setfield ("AvailVirtual", 0);
353  sys_struct.setfield ("AvailExtendedVirtual", 0);
354  }
355 
356  return ovl (proc_struct, sys_struct);
357 
358 #else
359  octave_unused_parameter (args);
360  error ("__wmemory__: Function is only supported on Windows platforms");
361 #endif
362 }
363 
364 #if defined (__MINGW32__)
365 
366 static void
367 MINGW_init ()
368 {
369  w32_init ();
370 }
371 
372 #endif
373 
374 #if defined (_MSC_VER)
375 
376 static void
377 MSVC_init ()
378 {
379  w32_init ();
380 }
381 
382 #endif
383 
384 // Return TRUE if NAME refers to an existing drive letter or UNC share
385 
386 bool
387 drive_or_unc_share (const std::string& name)
388 {
389 #if defined (OCTAVE_USE_WINDOWS_API)
390  std::size_t len = name.length ();
391  bool candidate = false;
392  if (len > 1 && isalpha(name[0]) && name[1]==':'
393  && (len == 2 || (len == 3 && name[2] == '\\')))
394  candidate = true;
395  if (len > 4 && name[0] == '\\' && name[1] == '\\')
396  {
397  // It starts with two slashes. Find the next slash.
398  std::size_t next_slash = name.find ('\\', 3);
399  if (next_slash != std::string::npos && len > next_slash+1)
400  {
401  // Check if it ends with the share
402  std::size_t last_slash = name.find ('\\', next_slash+1);
403  if (last_slash == std::string::npos
404  || (len > next_slash+2 && last_slash == len-1))
405  candidate = true;
406  }
407  }
408 
409  if (candidate)
410  {
411  // Open a handle to the file.
412  std::wstring wname = sys::u8_to_wstring (name);
413  HANDLE h
414  = CreateFileW (wname.c_str (), FILE_READ_ATTRIBUTES,
415  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
416  nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
417  nullptr);
418  if (h != INVALID_HANDLE_VALUE)
419  {
420  CloseHandle (h);
421  return true;
422  }
423  }
424 
425  return false;
426 
427 #else
428 
429  octave_unused_parameter (name);
430 
431  return false;
432 
433 #endif
434 }
435 
436 void
438 {
439  // Use a function from libgomp to force loading of OpenMP library.
440  // Otherwise, a dynamically loaded library making use of OpenMP such
441  // as GraphicsMagick will segfault on exit (bug #41699).
442 #if defined (HAVE_OMP_GET_NUM_THREADS)
443  omp_get_num_threads ();
444 #endif
445 
446 #if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
447  BSD_init ();
448 #elif defined (__MINGW32__)
449  MINGW_init ();
450 #elif defined (_MSC_VER)
451  MSVC_init ();
452 #endif
453 }
454 
455 void
457 {
458 #if defined (OCTAVE_USE_WINDOWS_API)
459  // Let us fail immediately without displaying any dialog.
460  SetProcessShutdownParameters (0x280, SHUTDOWN_NORETRY);
461 #endif
462 }
463 
464 // Set terminal in raw mode. From less-177.
465 //
466 // Change terminal to "raw mode", or restore to "normal" mode.
467 // "Raw mode" means
468 // 1. An outstanding read will complete on receipt of a single keystroke.
469 // 2. Input is not echoed.
470 // 3. On output, \n is mapped to \r\n.
471 // 4. \t is NOT expanded into spaces.
472 // 5. Signal-causing characters such as ctrl-C (interrupt),
473 // etc. are NOT disabled.
474 // It doesn't matter whether an input \n is mapped to \r, or vice versa.
475 
476 void
477 raw_mode (bool on, bool wait)
478 {
479  static bool curr_on = false;
480 
481  int tty_fd = STDIN_FILENO;
482  if (! octave_isatty_wrapper (tty_fd))
483  {
484  interpreter& interp = __get_interpreter__ ();
485 
486  if (interp.interactive () && ! application::forced_interactive ())
487  error ("stdin is not a tty!");
488  }
489 
490  if (on == curr_on)
491  return;
492 
493 #if defined (HAVE_TERMIOS_H)
494  {
495  struct termios s;
496  static struct termios save_term;
497 
498  if (on)
499  {
500  // Get terminal modes.
501 
502  tcgetattr (tty_fd, &s);
503 
504  // Save modes and set certain variables dependent on modes.
505 
506  save_term = s;
507  // ospeed = s.c_cflag & CBAUD;
508  // erase_char = s.c_cc[VERASE];
509  // kill_char = s.c_cc[VKILL];
510 
511  // Set the modes to the way we want them.
512 
513  s.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
514  s.c_oflag |= (OPOST | ONLCR);
515 #if defined (OCRNL)
516  s.c_oflag &= ~(OCRNL);
517 #endif
518 #if defined (ONOCR)
519  s.c_oflag &= ~(ONOCR);
520 #endif
521 #if defined (ONLRET)
522  s.c_oflag &= ~(ONLRET);
523 #endif
524  s.c_cc[VMIN] = (wait ? 1 : 0);
525  s.c_cc[VTIME] = 0;
526  }
527  else
528  {
529  // Restore saved modes.
530 
531  s = save_term;
532  }
533 
534  tcsetattr (tty_fd, wait ? TCSAFLUSH : TCSADRAIN, &s);
535  }
536 #elif defined (HAVE_TERMIO_H)
537  {
538  struct termio s;
539  static struct termio save_term;
540 
541  if (on)
542  {
543  // Get terminal modes.
544 
545  ioctl (tty_fd, TCGETA, &s);
546 
547  // Save modes and set certain variables dependent on modes.
548 
549  save_term = s;
550  // ospeed = s.c_cflag & CBAUD;
551  // erase_char = s.c_cc[VERASE];
552  // kill_char = s.c_cc[VKILL];
553 
554  // Set the modes to the way we want them.
555 
556  s.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
557  s.c_oflag |= (OPOST | ONLCR);
558 #if defined (OCRNL)
559  s.c_oflag &= ~(OCRNL);
560 #endif
561 #if defined (ONOCR)
562  s.c_oflag &= ~(ONOCR);
563 #endif
564 #if defined (ONLRET)
565  s.c_oflag &= ~(ONLRET);
566 #endif
567  s.c_cc[VMIN] = (wait ? 1 : 0);
568  }
569  else
570  {
571  // Restore saved modes.
572 
573  s = save_term;
574  }
575 
576  ioctl (tty_fd, TCSETAW, &s);
577  }
578 #elif defined (HAVE_SGTTY_H)
579  {
580  octave_unused_parameter (wait);
581 
582  struct sgttyb s;
583  static struct sgttyb save_term;
584 
585  if (on)
586  {
587  // Get terminal modes.
588 
589  ioctl (tty_fd, TIOCGETP, &s);
590 
591  // Save modes and set certain variables dependent on modes.
592 
593  save_term = s;
594  // ospeed = s.sg_ospeed;
595  // erase_char = s.sg_erase;
596  // kill_char = s.sg_kill;
597 
598  // Set the modes to the way we want them.
599 
600  s.sg_flags |= CBREAK;
601  s.sg_flags &= ~(ECHO);
602  }
603  else
604  {
605  // Restore saved modes.
606 
607  s = save_term;
608  }
609 
610  ioctl (tty_fd, TIOCSETN, &s);
611  }
612 #else
613 
614  octave_unused_parameter (wait);
615 
616  warn_disabled_feature ("", "raw mode console I/O");
617 
618  // Make sure the current mode doesn't toggle.
619  on = curr_on;
620 #endif
621 
622  curr_on = on;
623 }
624 
625 FILE *
626 popen (const char *command, const char *mode)
627 {
628 #if defined (__MINGW32__) || defined (_MSC_VER)
629  std::wstring wcommand = sys::u8_to_wstring (command);
630  std::wstring wmode = sys::u8_to_wstring (mode);
631 
632  // Use binary mode on Windows if unspecified
633  if (wmode.length () < 2)
634  wmode += L'b';
635 
636  return _wpopen (wcommand.c_str (), wmode.c_str ());
637 #else
638  return ::popen (command, mode);
639 #endif
640 }
641 
642 int
643 pclose (FILE *f)
644 {
645 #if defined (__MINGW32__) || defined (_MSC_VER)
646  return ::_pclose (f);
647 #else
648  return ::pclose (f);
649 #endif
650 }
651 
652 // Read one character from the terminal.
653 
654 int
655 kbhit (bool wait)
656 {
657 #if defined (HAVE__KBHIT) && defined (HAVE__GETCH)
658  // This essentially means we are on a Windows system.
659 
660  // The value to return when wait is false and no input is ready.
661  static constexpr int eof = std::istream::traits_type::eof ();
662 
663  int c;
664 
665  if (wait)
666  c = _getch ();
667  else
668  c = (! _kbhit ()) ? eof : _getch ();
669 
670 #else
671  raw_mode (true, wait);
672 
673  // Get current handler.
674  interrupt_handler saved_interrupt_handler
675  = ignore_interrupts ();
676 
677  // Restore it, disabling system call restarts (if possible) so the
678  // read can be interrupted.
679 
680  set_interrupt_handler (saved_interrupt_handler, false);
681 
682  int c = std::cin.get ();
683 
684  if (std::cin.fail () || std::cin.eof ())
685  {
686  std::cin.clear ();
687  clearerr (stdin);
688  }
689 
690  // Restore it, enabling system call restarts (if possible).
691  set_interrupt_handler (saved_interrupt_handler, true);
692 
693  raw_mode (false, true);
694 #endif
695 
696  return c;
697 }
698 
699 std::string
701 {
702 #if defined (OCTAVE_USE_WINDOWS_API)
703 
704  std::string retval;
705 
706 #if defined (P_tmpdir)
707  retval = P_tmpdir;
708 #endif
709 
710  // Apparently some versions of MinGW and MSVC either don't define
711  // P_tmpdir, or they define it to a single backslash, neither of which
712  // is particularly helpful.
713 
714  if (retval.empty () || retval == R"(\)")
715  {
716  retval = sys::env::getenv ("TEMP");
717 
718  if (retval.empty ())
719  retval = sys::env::getenv ("TMP");
720 
721  if (retval.empty ())
722  retval = R"(c:\temp)";
723  }
724 
725  return retval;
726 
727 #elif defined (P_tmpdir)
728 
729  return P_tmpdir;
730 
731 #else
732 
733  return "/tmp";
734 
735 #endif
736 }
737 
738 DEFUN (clc, , ,
739  doc: /* -*- texinfo -*-
740 @deftypefn {} {} clc ()
741 @deftypefnx {} {} home ()
742 Clear the terminal screen and move the cursor to the upper left corner.
743 
744 Programming Note: @code{home} is an alias for @code{clc} and can be used
745 interchangeably.
746 @end deftypefn */)
747 {
748  bool skip_redisplay = true;
749 
750  command_editor::clear_screen (skip_redisplay);
751 
752  return ovl ();
753 }
754 
755 DEFALIAS (home, clc);
756 
757 DEFUN (getenv, args, ,
758  doc: /* -*- texinfo -*-
759 @deftypefn {} {@var{val} =} getenv ("@var{var}")
760 Return the value of the environment variable @var{var}.
761 
762 For example,
763 
764 @example
765 getenv ("PATH")
766 @end example
767 
768 @noindent
769 returns a string containing the value of your path.
770 @seealso{setenv, unsetenv, isenv}
771 @end deftypefn */)
772 {
773  if (args.length () != 1)
774  print_usage ();
775 
776  std::string name = args(0).string_value ();
777 
778  return ovl (sys::env::getenv (name));
779 }
780 
781 /*
782 %!assert (ischar (getenv ("OCTAVE_HOME")))
783 */
784 
785 DEFUN (isenv, args, ,
786  doc: /* -*- texinfo -*-
787 @deftypefn {} {@var{tf} =} isenv (@var{var})
788 Return true if the variable @var{var} is an environment variable, and false
789 otherwise.
790 
791 For example,
792 
793 @example
794 tf = isenv ("PATH")
795 @end example
796 
797 @noindent
798 will typically return true on UNIX systems because @qcode{"PATH"} is an
799 environment variable for UNIX.
800 @seealso{getenv, setenv, unsetenv}
801 @end deftypefn */)
802 {
803  if (args.length () != 1)
804  print_usage ();
805 
806  std::string name = args(0).xstring_value ("isenv: VAR must be a string");
807 
808  return ovl (sys::env::isenv (name));
809 }
810 
811 /*
812 %!test
813 %! setenv ("dummy_variable_that_cannot_matter", "foobar");
814 %! assert (isenv ("dummy_variable_that_cannot_matter"), true);
815 %! unsetenv ("dummy_variable_that_cannot_matter");
816 %! assert (isenv ("dummy_variable_that_cannot_matter"), false);
817 
818 %!error <VAR must be a string> isenv (struct ())
819 */
820 
821 DEFUN (setenv, args, ,
822  doc: /* -*- texinfo -*-
823 @deftypefn {} {} setenv ("@var{var}", @var{value})
824 @deftypefnx {} {} setenv (@var{var})
825 @deftypefnx {} {} putenv (@dots{})
826 Set the value of the environment variable @var{var} to @var{value}.
827 
828 If no @var{value} is specified then the variable will be assigned the null
829 string.
830 
831 Programming Note: @code{putenv} is an alias for @code{setenv} and can be used
832 interchangeably.
833 @seealso{unsetenv, getenv, isenv}
834 @end deftypefn */)
835 {
836  int nargin = args.length ();
837 
838  if (nargin < 1 || nargin > 2)
839  print_usage ();
840 
841  std::string var = args(0).xstring_value ("setenv: VAR must be a string");
842 
843  std::string val = (nargin == 2
844  ? args(1).xstring_value ("setenv: VALUE must be a string")
845  : "");
846 
847  sys::env::putenv (var, val);
848 
849  return ovl ();
850 }
851 
852 DEFALIAS (putenv, setenv);
853 
854 /*
855 %!test
856 %! setenv ("dummy_variable_that_cannot_matter", "foobar");
857 %! assert (getenv ("dummy_variable_that_cannot_matter"), "foobar");
858 %! unsetenv ("dummy_variable_that_cannot_matter");
859 %! assert (getenv ("dummy_variable_that_cannot_matter"), "");
860 */
861 
862 DEFUN (unsetenv, args, ,
863  doc: /* -*- texinfo -*-
864 @deftypefn {} {} unsetenv ("@var{var}")
865 @deftypefnx {} {@var{status} =} unsetenv ("@var{var}")
866 Delete the environment variable @var{var}.
867 
868 Return 0 if the variable was deleted, or did not exist, and -1 if an error
869 occurred.
870 @seealso{setenv, getenv, isenv}
871 @end deftypefn */)
872 {
873  if (args.length () != 1)
874  print_usage ();
875 
876  std::string tmp = args(0).string_value ();
877 
878  return ovl (sys::unsetenv_wrapper (tmp));
879 }
880 
881 /*
882 ## Test for unsetenv is in setenv test
883 */
884 
885 #if defined (OCTAVE_USE_WINDOWS_API)
886 
887 static void
888 reg_close_key_wrapper (HKEY key)
889 {
890  RegCloseKey (key);
891 }
892 
893 // This function is also used in ov-java.cc, so don't declare static.
894 // Maybe the functions that use it should be here instead?
895 
896 LONG
897 get_regkey_value (HKEY h_rootkey, const std::string subkey,
898  const std::string name, octave_value& value)
899 {
900  LONG result;
901  HKEY h_subkey;
902 
903  std::wstring wsubkey = sys::u8_to_wstring (subkey);
904  result = RegOpenKeyExW (h_rootkey, wsubkey.c_str (), 0, KEY_READ,
905  &h_subkey);
906 
907  if (result != ERROR_SUCCESS)
908  return result;
909 
910  unwind_action restore_keys ([=] () { reg_close_key_wrapper (h_subkey); });
911 
912  std::wstring wname = sys::u8_to_wstring (name);
913  DWORD length = 0;
914  result = RegQueryValueExW (h_subkey, wname.c_str (), nullptr, nullptr,
915  nullptr, &length);
916  if (result != ERROR_SUCCESS)
917  return result;
918 
919  DWORD type = 0;
920  OCTAVE_LOCAL_BUFFER (BYTE, data, length);
921  result = RegQueryValueExW (h_subkey, wname.c_str (), nullptr, &type,
922  data, &length);
923  if (result != ERROR_SUCCESS)
924  return result;
925 
926  if (type == REG_DWORD)
927  value = octave_int32 (*(reinterpret_cast<DWORD *> (data)));
928  else if (type == REG_SZ || type == REG_EXPAND_SZ)
929  {
930  // strings in registry might not be zero terminated
931  wchar_t *dataw = reinterpret_cast<wchar_t *> (data);
932  DWORD lengthw = length / sizeof (wchar_t);
933  std::wstring reg_string
934  = std::wstring (dataw, lengthw - (dataw[lengthw-1]==0));
935  value = string_vector (sys::u8_from_wstring (reg_string));
936  }
937 
938  return result;
939 }
940 
941 static LONG
942 get_regkey_names (HKEY h_rootkey, const std::string subkey,
943  std::list<std::string>& fields)
944 {
945  LONG retval;
946  HKEY h_subkey;
947 
948  fields.clear ();
949 
950  std::wstring wsubkey = sys::u8_to_wstring (subkey);
951  retval = RegOpenKeyExW (h_rootkey, wsubkey.c_str (), 0, KEY_READ,
952  &h_subkey);
953  if (retval != ERROR_SUCCESS)
954  return retval;
955 
956  DWORD idx = 0;
957  const int MAX_VALUE_NAME_SIZE = 32766;
958  wchar_t value_name[MAX_VALUE_NAME_SIZE+1];
959  DWORD value_name_size = MAX_VALUE_NAME_SIZE;
960 
961  while (true)
962  {
963  retval = RegEnumValueW (h_subkey, idx, value_name, &value_name_size,
964  nullptr, nullptr, nullptr, nullptr);
965  if (retval != ERROR_SUCCESS)
966  break;
967  fields.push_back (sys::u8_from_wstring (value_name));
968  value_name_size = MAX_VALUE_NAME_SIZE;
969  idx++;
970  }
971 
972  if (retval == ERROR_NO_MORE_ITEMS)
973  retval = ERROR_SUCCESS;
974 
975  RegCloseKey (h_subkey);
976 
977  return retval;
978 }
979 
980 #endif
981 
982 DEFUN (winqueryreg, args, ,
983  doc: /* -*- texinfo -*-
984 @deftypefn {} {@var{value} =} winqueryreg (@var{rootkey}, @var{subkey}, @var{valuename})
985 @deftypefnx {} {@var{value} =} winqueryreg (@var{rootkey}, @var{subkey})
986 @deftypefnx {} {@var{names} =} winqueryreg (@code{"name"}, @var{rootkey}, @var{subkey})
987 
988 Query names or value from the Windows registry.
989 
990 On Windows, return the value of the registry key @var{subkey} from the root key
991 @var{rootkey}. You can specify the name of the queried registry value with the
992 optional argument @var{valuename}. Otherwise, if called with only two
993 arguments or @var{valuename} is empty, then the default value of @var{subkey}
994 is returned. If the registry value is of type @nospell{@qcode{"REG_DWORD"}}
995 then @var{value} is of class int32. If the value is of the type
996 @nospell{@qcode{"REG_SZ"}} or @nospell{@qcode{"REG_EXPAND_SZ"}} a string is
997 returned.
998 
999 If the first argument is @qcode{"name"}, a cell array of strings with the names
1000 of the values at that key is returned.
1001 
1002 The variable @var{rootkey} must be a string with a valid root key identifier:
1003 
1004 @table @asis
1005 @item @nospell{HKCR}
1006 @itemx @nospell{HKEY_CLASSES_ROOT}
1007 
1008 @item @nospell{HKEY_CURRENT_CONFIG}
1009 
1010 @item @nospell{HKCU}
1011 @itemx @nospell{HKEY_CURRENT_USER}
1012 
1013 @item @nospell{HKLM}
1014 @itemx @nospell{HKEY_LOCAL_MACHINE}
1015 
1016 
1017 @item @nospell{HKU}
1018 @itemx @nospell{HKEY_USERS}
1019 
1020 
1021 @item @nospell{HKEY_PERFORMANCE_DATA}
1022 
1023 @end table
1024 
1025 Examples:
1026 
1027 Get a list of value names at the key
1028 @nospell{@qcode{'HKCU@backslashchar{}Environment'}}:
1029 
1030 @example
1031 @group
1032 @var{valuenames} = winqueryreg ("name", "HKEY_CURRENT_USER", ...
1033  "Environment");
1034 @end group
1035 @end example
1036 
1037 For each @var{valuenames}, display the value:
1038 
1039 @example
1040 @group
1041 for @var{k} = 1:numel (@var{valuenames})
1042  @var{val} = winqueryreg ("HKEY_CURRENT_USER", "Environment", ...
1043  @var{valuenames}@{@var{k}@});
1044  @var{str} = sprintf ("%s = %s", @var{valuenames}@{@var{k}@}, num2str (@var{val}));
1045  disp (@var{str});
1046 endfor
1047 @end group
1048 @end example
1049 
1050 On non-Windows platforms this function fails with an error.
1051 @end deftypefn */)
1052 {
1053 #if defined (OCTAVE_USE_WINDOWS_API)
1054  if ((args.length () < 2) || (args.length () > 3))
1055  print_usage ();
1056 
1057  // Input check
1058  std::string rootkey_name
1059  = args(0).xstring_value ("winqueryreg: the first argument must be 'name' "
1060  "or a valid ROOTKEY identifier");
1061  std::string subkey_name = "";
1062  std::string value_name = "";
1063  bool get_names = false;
1064  if (rootkey_name.compare ("name") == 0)
1065  {
1066  if (args.length () < 3)
1067  error ("winqueryreg: if the first argument is 'name', "
1068  "ROOTKEY and SUBKEY must be given");
1069  get_names = true;
1070  rootkey_name
1071  = args(1).xstring_value ("winqueryreg: ROOTKEY must be a string");
1072  subkey_name
1073  = args(2).xstring_value ("winqueryreg: SUBKEY must be a string");
1074  }
1075  else
1076  {
1077  subkey_name
1078  = args(1).xstring_value ("winqueryreg: SUBKEY must be a string");
1079 
1080  if (args.length () == 3)
1081  value_name
1082  = args(2).xstring_value ("winqueryreg: VALUENAME must be a string");
1083  }
1084 
1085  // Get rootkey handle
1086  HKEY h_rootkey;
1087  if (rootkey_name == "HKEY_CLASSES_ROOT" || rootkey_name == "HKCR")
1088  h_rootkey = HKEY_CLASSES_ROOT;
1089  else if (rootkey_name == "HKEY_CURRENT_CONFIG")
1090  h_rootkey = HKEY_CURRENT_CONFIG;
1091  else if (rootkey_name == "HKEY_CURRENT_USER" || rootkey_name == "HKCU")
1092  h_rootkey = HKEY_CURRENT_USER;
1093  else if (rootkey_name == "HKEY_LOCAL_MACHINE" || rootkey_name == "HKLM")
1094  h_rootkey = HKEY_LOCAL_MACHINE;
1095  else if (rootkey_name == "HKEY_PERFORMANCE_DATA")
1096  h_rootkey = HKEY_PERFORMANCE_DATA;
1097  else if (rootkey_name == "HKEY_USERS" || rootkey_name == "HKU")
1098  h_rootkey = HKEY_USERS;
1099  else
1100  error ("winqueryreg: ROOTKEY is not a valid root key identifier");
1101 
1102  if (get_names)
1103  {
1104  std::list<std::string> fields;
1105 
1106  LONG retval = get_regkey_names (h_rootkey, subkey_name, fields);
1107  if (retval != ERROR_SUCCESS)
1108  error ("winqueryreg: error %ld reading names from registry", retval);
1109 
1110  Cell fieldnames (dim_vector (1, fields.size ()));
1111  std::size_t i = 0;
1112  for (const auto& it : fields)
1113  fieldnames(i++) = it;
1114 
1115  return ovl (fieldnames);
1116  }
1117  else
1118  {
1119  octave_value key_val;
1120  LONG retval = get_regkey_value (h_rootkey, subkey_name,
1121  value_name, key_val);
1122  if (retval == ERROR_FILE_NOT_FOUND)
1123  error ("winqueryreg: no value found for '%s' at %s\\%s",
1124  value_name.c_str (), rootkey_name.c_str (),
1125  subkey_name.c_str ());
1126  if (retval != ERROR_SUCCESS)
1127  error ("winqueryreg: error %ld reading the specified key", retval);
1128 
1129  return ovl (key_val);
1130  }
1131 #else
1132 
1133  octave_unused_parameter (args);
1134 
1135  error ("winqueryreg: function is only supported on Windows platforms");
1136 
1137 #endif
1138 }
1139 
1140 /*
1141 %!testif ; ispc ()
1142 %! assert (ischar (winqueryreg ("HKEY_LOCAL_MACHINE",
1143 %! 'SOFTWARE\Microsoft\Windows\CurrentVersion',
1144 %! "ProgramFilesDir")));
1145 %!testif ; ispc ()
1146 %! assert (isa (winqueryreg ("HKEY_LOCAL_MACHINE",
1147 %! 'SYSTEM\CurrentControlSet\Control\FileSystem',
1148 %! "Win31FileSystem"), "int32"));
1149 %!testif ; ispc ()
1150 %! assert (iscellstr (winqueryreg ("name", "HKEY_LOCAL_MACHINE",
1151 %! 'SOFTWARE\Microsoft\Windows\CurrentVersion')));
1152 %!testif ; ispc ()
1153 %! fail ('winqueryreg (1, ''SOFTWARE\Microsoft\Windows\CurrentVersion'')',
1154 %! "first argument must be 'name' or a valid ROOTKEY identifier");
1155 %!testif ; ispc ()
1156 %! fail ('winqueryreg ("HKEY_LOCAL_MACHINE", 1)', "SUBKEY must be a string");
1157 %!testif ; ispc ()
1158 %! fail (['winqueryreg ("HKEY_LOCAL_MACHINE", ', ...
1159 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'', 1)'],
1160 %! "VALUENAME must be a string");
1161 %!testif ; ispc ()
1162 %! fail (['winqueryreg ("FOO", ', ...
1163 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'')'],
1164 %! "ROOTKEY is not a valid root key identifier");
1165 %!testif ; ispc ()
1166 %! fail ('winqueryreg ("HKEY_LOCAL_MACHINE", ''FOO\bar'')',
1167 %! "no value found for");
1168 %!testif ; ispc ()
1169 %! fail (['winqueryreg ("HKEY_LOCAL_MACHINE", ', ...
1170 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'', "foo")'],
1171 %! "no value found for");
1172 %!testif ; ispc ()
1173 %! fail ('winqueryreg ("name", "HKEY_LOCAL_MACHINE")',
1174 %! "if the first argument is 'name', ROOTKEY and SUBKEY must be given");
1175 %!testif ; ispc ()
1176 %! fail (['winqueryreg ("name", 1, ', ...
1177 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'')'],
1178 %! "ROOTKEY must be a string");
1179 %!testif ; ispc ()
1180 %! fail ('winqueryreg ("name", "HKEY_LOCAL_MACHINE", 1)',
1181 %! "SUBKEY must be a string");
1182 */
1183 
1184 // FIXME: perhaps kbhit should also be able to print a prompt?
1185 
1186 DEFMETHOD (kbhit, interp, args, ,
1187  doc: /* -*- texinfo -*-
1188 @deftypefn {} {@var{c} =} kbhit ()
1189 @deftypefnx {} {@var{c} =} kbhit (1)
1190 Read a single keystroke from the keyboard.
1191 
1192 If called with an argument (typically 1), don't wait for a keypress and
1193 immediately return the next keystroke in the keyboard input buffer or an empty
1194 string ("") if no keystroke is available.
1195 
1196 For example,
1197 
1198 @example
1199 c = kbhit ();
1200 @end example
1201 
1202 @noindent
1203 will set @var{c} to the next character typed at the keyboard as soon as it is
1204 typed.
1205 
1206 @example
1207 c = kbhit (1);
1208 @end example
1209 
1210 @noindent
1211 is identical to the above example, but doesn't wait for a keypress, returning
1212 the empty string if no key is available.
1213 @seealso{input, pause}
1214 @end deftypefn */)
1215 {
1216  // FIXME: add timeout and default value args?
1217 
1218  Fdrawnow (interp);
1219 
1220  int c = kbhit (args.length () == 0);
1221 
1222  if (c == -1)
1223  c = 0;
1224 
1225  char s[2] = { static_cast<char> (c), '\0' };
1226 
1227  return octave_value (s);
1228 }
1229 
1230 // State of the pause system
1231 static bool Vpause_enabled = true;
1232 
1233 DEFMETHOD (pause, interp, args, nargout,
1234  doc: /* -*- texinfo -*-
1235 @deftypefn {} {} pause ()
1236 @deftypefnx {} {} pause (@var{n})
1237 @deftypefnx {} {@var{old_state} =} pause ("on")
1238 @deftypefnx {} {@var{old_state} =} pause ("off")
1239 @deftypefnx {} {@var{old_state} =} pause ("query")
1240 Suspend the execution of the program or change the state of the pause function.
1241 
1242 If invoked without an input arguments then the program is suspended until a
1243 character is typed. If argument @var{n} is a positive real value, it indicates
1244 the number of seconds the program shall be suspended, for example:
1245 
1246 @example
1247 @group
1248 tic; pause (0.05); toc
1249  @print{} Elapsed time is 0.05039 seconds.
1250 @end group
1251 @end example
1252 
1253 The following example prints a message and then waits 5 seconds before clearing
1254 the screen.
1255 
1256 @example
1257 @group
1258 disp ("wait please...");
1259 pause (5);
1260 clc;
1261 @end group
1262 @end example
1263 
1264 If invoked with a string argument @qcode{"on"}, @qcode{"off"}, or
1265 @qcode{"query"}, the state of the pause function is changed or queried. When
1266 the state is @qcode{"off"}, the pause function returns immediately. The
1267 optional return value contains the previous state of the pause function. In
1268 the following example pause is disabled locally:
1269 
1270 @example
1271 @group
1272 old_state = pause ("off");
1273 tic; pause (0.05); toc
1274  @print{} Elapsed time is 3.00407e-05 seconds.
1275 pause (old_state);
1276 @end group
1277 @end example
1278 
1279 While the program is suspended Octave still handles figures painting and
1280 graphics callbacks execution.
1281 
1282 @seealso{kbhit}
1283 @end deftypefn */)
1284 {
1285  octave_value_list retval;
1286 
1287  int nargin = args.length ();
1288 
1289  if (nargin > 1)
1290  print_usage ();
1291 
1292  if (nargin == 1 && args(0).is_string ())
1293  {
1294  bool saved_state = Vpause_enabled;
1295  std::string state = args(0).string_value ();
1296 
1297  if (state == "on")
1298  Vpause_enabled = true;
1299  else if (state == "off")
1300  Vpause_enabled = false;
1301  else if (state == "query")
1302  ;// Do nothing
1303  else
1304  error (R"(pause: first argument must be "on", "off", or "query")");
1305 
1306  if (nargout > 0 || state == "query")
1307  retval.append (saved_state ? "on" : "off");
1308  }
1309  else if (Vpause_enabled)
1310  {
1311  double dval;
1312 
1313  if (nargin == 0)
1314  dval = octave_Inf;
1315  else
1316  dval = args(0).xdouble_value ("pause: N must be a scalar real value");
1317 
1318  if (math::isnan (dval))
1319  warning ("pause: NaN is an invalid delay");
1320  else
1321  {
1322  Fdrawnow (interp);
1323 
1324  sleep (dval, true);
1325  }
1326  }
1327 
1328  return retval;
1329 }
1330 
1331 /*
1332 %!test
1333 %! pause (1);
1334 
1335 %!error pause (1, 2)
1336 */
1337 
1338 // FIXME: maybe this should only return 1 if IEEE floating
1339 // point functions really work.
1340 
1341 DEFUN (isieee, , ,
1342  doc: /* -*- texinfo -*-
1343 @deftypefn {} {@var{tf} =} isieee ()
1344 Return true if your computer @emph{claims} to conform to the IEEE standard
1345 for floating point calculations.
1346 
1347 No actual tests are performed.
1348 @end deftypefn */)
1349 {
1351 
1352  return ovl (flt_fmt == mach_info::flt_fmt_ieee_little_endian
1353  || flt_fmt == mach_info::flt_fmt_ieee_big_endian);
1354 }
1355 
1356 /*
1357 %!assert (islogical (isieee ()))
1358 */
1359 
1361  doc: /* -*- texinfo -*-
1362 @deftypefn {} {@var{fmtstr} =} native_float_format ()
1363 Return the native floating point format as a string.
1364 @end deftypefn */)
1365 {
1367 
1368  return ovl (mach_info::float_format_as_string (flt_fmt));
1369 }
1370 
1371 /*
1372 %!assert (ischar (native_float_format ()))
1373 */
1374 
1375 DEFUN (tilde_expand, args, ,
1376  doc: /* -*- texinfo -*-
1377 @deftypefn {} {@var{newstr} =} tilde_expand (@var{string})
1378 @deftypefnx {} {@var{newcstr} =} tilde_expand (@var{cellstr})
1379 Perform tilde expansion on @var{string}.
1380 
1381 If @var{string} begins with a tilde character, (@samp{~}), all of the
1382 characters preceding the first slash (or all characters, if there is no
1383 slash) are treated as a possible user name, and the tilde and the following
1384 characters up to the slash are replaced by the home directory of the named
1385 user. If the tilde is followed immediately by a slash, the tilde is
1386 replaced by the home directory of the user running Octave.
1387 
1388 If the input is a cell array of strings @var{cellstr} then tilde expansion
1389 is performed on each string element.
1390 
1391 Examples:
1392 
1393 @example
1394 @group
1395 tilde_expand ("~joeuser/bin")
1396  @result{} "/home/joeuser/bin"
1397 tilde_expand ("~/bin")
1398  @result{} "/home/jwe/bin"
1399 @end group
1400 @end example
1401 @end deftypefn */)
1402 {
1403  if (args.length () != 1)
1404  print_usage ();
1405 
1406  octave_value arg = args(0);
1407 
1408  string_vector sv =
1409  arg.xstring_vector_value ("tilde_expand: argument must be char or cellstr object");
1410 
1411  sv = sys::file_ops::tilde_expand (sv);
1412 
1413  if (arg.iscellstr ())
1414  return ovl (Cell (arg.dims (), sv));
1415  else
1416  return ovl (sv);
1417 }
1418 
1419 /*
1420 %!test
1421 %! home = get_home_directory ();
1422 %! assert (tilde_expand ("~/foobar"), [home "/foobar"]);
1423 %! assert (tilde_expand ("/foo/bar"), "/foo/bar");
1424 %! assert (tilde_expand ("foo/bar"), "foo/bar");
1425 */
1426 
1427 DEFUN (get_home_directory, , ,
1428  doc: /* -*- texinfo -*-
1429 @deftypefn {} {@var{homedir} =} get_home_directory ()
1430 Return the current home directory.
1431 
1432 On most systems, this is equivalent to @code{getenv ("HOME")}. On Windows
1433 systems, if the environment variable @env{HOME} is not set then it is
1434 equivalent to
1435 @code{fullfile (getenv ("HOMEDRIVE"), getenv ("HOMEPATH"))}
1436 @seealso{getenv}
1437 @end deftypefn */)
1438 {
1439  return ovl (sys::env::get_home_directory ());
1440 }
1441 
1442 /*
1443 %!test
1444 %! if (! ispc ())
1445 %! assert (get_home_directory (), getenv ("HOME"));
1446 %! endif
1447 */
1448 
1449 DEFUN (__blas_version__, , ,
1450  doc: /* -*- texinfo -*-
1451 @deftypefn {} {@var{verstr} =} __blas_version__ ()
1452 Undocumented internal function.
1453 @end deftypefn */)
1454 {
1455  return ovl (sys::blas_version ());
1456 }
1457 
1458 DEFUN (__lapack_version__, , ,
1459  doc: /* -*- texinfo -*-
1460 @deftypefn {} {@var{verstr} =} __lapack_version__ ()
1461 Undocumented internal function.
1462 @end deftypefn */)
1463 {
1464  return ovl (sys::lapack_version ());
1465 }
1466 
1467 OCTAVE_END_NAMESPACE(octave)
octave_value_list Fdrawnow(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
Definition: graphics.cc:13226
octave_value_list Fsystem(const octave_value_list &=octave_value_list(), int=0)
Definition: toplev.cc:240
Definition: Cell.h:43
static bool forced_interactive()
Definition: octave.cc:329
static bool prefer_env_winsize(bool)
Definition: cmd-edit.cc:1616
static void clear_screen(bool skip_redisplay=false)
Definition: cmd-edit.cc:1254
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
bool interactive() const
Definition: interpreter.h:165
void setfield(const std::string &key, const octave_value &val)
Definition: oct-map.cc:190
octave_value_list & append(const octave_value &val)
Definition: ovl.cc:98
octave_idx_type length() const
Definition: ovl.h:113
string_vector xstring_vector_value(const char *fmt,...) const
bool iscellstr() const
Definition: ov.h:607
dim_vector dims() const
Definition: ov.h:541
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string bin_dir()
void print_usage(void)
Definition: defun-int.h:72
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:111
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition: defun.h:160
void warning(const char *fmt,...)
Definition: error.cc:1063
void() error(const char *fmt,...)
Definition: error.cc:988
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:318
interpreter & __get_interpreter__()
#define octave_Inf
Definition: lo-ieee.h:40
bool isnan(bool)
Definition: lo-mappers.h:178
F77_RET_T const F77_DBLE const F77_DBLE * f
std::string u8_from_wstring(const std::wstring &wchar_string)
Definition: lo-sysdep.cc:746
std::wstring u8_to_wstring(const std::string &utf8_string)
Definition: lo-sysdep.cc:723
int unsetenv_wrapper(const std::string &name)
Definition: lo-sysdep.cc:698
std::string lapack_version()
Definition: lo-sysinfo.cc:164
std::string blas_version()
Definition: lo-sysinfo.cc:45
std::string float_format_as_string(float_format flt_fmt)
Definition: mach-info.cc:111
float_format native_float_format()
Definition: mach-info.cc:67
float_format
Definition: mach-info.h:38
@ flt_fmt_ieee_big_endian
Definition: mach-info.h:44
@ flt_fmt_ieee_little_endian
Definition: mach-info.h:43
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:289
octave_int< int32_t > octave_int32
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
#define ECHO
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
interrupt_handler ignore_interrupts()
Definition: sighandlers.cc:338
interrupt_handler set_interrupt_handler(const volatile interrupt_handler &h, bool restart_syscalls)
Definition: sighandlers.cc:349
#define FSYSTEM_OPEN_STR
#define STDIN_FILENO
Definition: sysdep.cc:92
void raw_mode(bool, bool wait=true)
int pclose(FILE *f)
FILE * popen(const char *command, const char *mode)
void sysdep_cleanup()
std::string get_P_tmpdir()
int kbhit(bool wait=true)
void sysdep_init()
bool drive_or_unc_share(const std::string &)
void set_application_id()
int octave_isatty_wrapper(int fd)
void sleep(double seconds, bool do_graphics_events=false)
F77_RET_T len
Definition: xerbla.cc:61