GNU Octave  4.4.1
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-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <cmath>
28 #include <cstddef>
29 
30 #include <iostream>
31 #include <string>
32 
33 #if defined (HAVE_TERMIOS_H)
34 # include <termios.h>
35 #elif defined (HAVE_TERMIO_H)
36 # include <termio.h>
37 #elif defined (HAVE_SGTTY_H)
38 # include <sgtty.h>
39 #endif
40 
41 #if defined (HAVE_CONIO_H)
42 # include <conio.h>
43 #endif
44 
45 #if defined (HAVE_SYS_IOCTL_H)
46 # include <sys/ioctl.h>
47 #endif
48 
49 #if defined (HAVE_FLOATINGPOINT_H)
50 # include <floatingpoint.h>
51 #endif
52 
53 #if defined (HAVE_IEEEFP_H)
54 # include <ieeefp.h>
55 #endif
56 
57 #if defined (HAVE_OMP_H)
58 # include <omp.h>
59 #endif
60 
61 #include "cmd-edit.h"
62 #include "file-ops.h"
63 #include "lo-mappers.h"
64 #include "lo-sysinfo.h"
65 #include "mach-info.h"
66 #include "oct-env.h"
67 #include "unistd-wrappers.h"
68 #include "unsetenv-wrapper.h"
69 
70 #include "builtin-defun-decls.h"
71 #include "Cell.h"
72 #include "defun.h"
73 #include "error.h"
74 #include "errwarn.h"
75 #include "input.h"
76 #include "octave.h"
77 #include "ov.h"
78 #include "ovl.h"
79 #include "pager.h"
80 #include "parse.h"
81 #include "sighandlers.h"
82 #include "sysdep.h"
83 #include "interpreter.h"
84 #include "utils.h"
85 #include "file-stat.h"
86 
87 #if ! defined (STDIN_FILENO)
88 # define STDIN_FILENO 1
89 #endif
90 
91 #if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
92 static void
93 BSD_init (void)
94 {
95 # if defined (HAVE_FLOATINGPOINT_H)
96  // Disable trapping on common exceptions.
97 # if ! defined (FP_X_DNML)
98 # define FP_X_DNML 0
99 # endif
100  fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
101 # endif
102 }
103 #endif
104 
105 #if defined (__MINGW32__) || defined (_MSC_VER)
106 
107 #define WIN32_LEAN_AND_MEAN
108 #include <windows.h>
109 #include <tlhelp32.h>
110 #include <shellapi.h>
111 
112 static void
113 w32_set_octave_home (void)
114 {
116 
117  HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE
118 #if defined (TH32CS_SNAPMODULE32)
119  | TH32CS_SNAPMODULE32
120 #endif
121  , 0);
122 
123  if (h != INVALID_HANDLE_VALUE)
124  {
125  MODULEENTRY32 mod_info;
126 
127  ZeroMemory (&mod_info, sizeof (mod_info));
128  mod_info.dwSize = sizeof (mod_info);
129 
130  if (Module32First (h, &mod_info))
131  {
132  do
133  {
134  std::string mod_name (mod_info.szModule);
135 
136  if (mod_name.find ("octinterp") != std::string::npos)
137  {
138  bin_dir = mod_info.szExePath;
139  if (! bin_dir.empty () && bin_dir.back () != '\\')
140  bin_dir.push_back ('\\');
141  break;
142  }
143  }
144  while (Module32Next (h, &mod_info));
145  }
146 
147  CloseHandle (h);
148  }
149 
150  if (! bin_dir.empty ())
151  {
152  size_t pos = bin_dir.rfind (R"(\bin\)");
153 
154  if (pos != std::string::npos)
155  octave::sys::env::putenv ("OCTAVE_HOME", bin_dir.substr (0, pos));
156  }
157 }
158 
159 static void
160 w32_init (void)
161 {
162  w32_set_octave_home ();
163 
165 }
166 
167 #endif
168 
169 // Set app id if we have the SetCurrentProcessExplicitAppUserModelID
170 // available (>= Win7). FIXME: Could we check for existence of this
171 // function in the configure script instead of dynamically loading
172 // shell32.dll?
173 
174 void
176 {
177 #if defined (__MINGW32__) || defined (_MSC_VER)
178 
179  typedef HRESULT (WINAPI *SETCURRENTAPPID)(PCWSTR AppID);
180 
181  HMODULE hShell = LoadLibrary ("shell32.dll");
182 
183  if (hShell)
184  {
185  SETCURRENTAPPID pfnSetCurrentProcessExplicitAppUserModelID =
186  reinterpret_cast<SETCURRENTAPPID> (GetProcAddress (hShell,
187  "SetCurrentProcessExplicitAppUserModelID"));
188 
189  if (pfnSetCurrentProcessExplicitAppUserModelID)
190  pfnSetCurrentProcessExplicitAppUserModelID (L"gnu.octave." VERSION);
191 
192  FreeLibrary (hShell);
193  }
194 
195 #endif
196 }
197 
198 DEFUN (__open_with_system_app__, args, ,
199  doc: /* -*- texinfo -*-
200 @deftypefn {} {} __open_with_system_app__ (@var{file})
201 Undocumented internal function.
202 @end deftypefn */)
203 {
204  if (args.length () != 1)
205  print_usage ();
206 
207  std::string file = args(0).xstring_value ("__open_with_system_app__: argument must be a filename");
208 
210 
211 #if defined (OCTAVE_USE_WINDOWS_API)
212  HINSTANCE status = ShellExecute (0, 0, file.c_str (), 0, 0,
213  SW_SHOWNORMAL);
214 
215  // ShellExecute returns a value greater than 32 if successful.
216  retval = (reinterpret_cast<ptrdiff_t> (status) > 32);
217 #elif defined (__APPLE__)
219  = Fsystem (ovl ("open " + file + " 2> /dev/null",
220  false, "async"),
221  1);
222 
223  retval = (tmp(0).double_value () == 0);
224 #else
226  = Fsystem (ovl ("xdg-open " + file + " 2> /dev/null",
227  false, "async"),
228  1);
229 
230  retval = (tmp(0).double_value () == 0);
231 #endif
232 
233  return retval;
234 }
235 
236 #if defined (__MINGW32__)
237 static void
238 MINGW_init (void)
239 {
240  w32_init ();
241 }
242 #endif
243 
244 #if defined (_MSC_VER)
245 static void
246 MSVC_init (void)
247 {
248  w32_init ();
249 }
250 #endif
251 
252 // Return TRUE if FILE1 and FILE2 refer to the same (physical) file.
253 
254 bool
255 same_file_internal (const std::string& file1, const std::string& file2)
256 {
257 #if defined (OCTAVE_USE_WINDOWS_API)
258 
259  bool retval = false;
260 
261  const char *f1 = file1.c_str ();
262  const char *f2 = file2.c_str ();
263 
264  bool f1_is_dir = GetFileAttributes (f1) & FILE_ATTRIBUTE_DIRECTORY;
265  bool f2_is_dir = GetFileAttributes (f2) & FILE_ATTRIBUTE_DIRECTORY;
266 
267  // Windows native code
268  // Reference: http://msdn2.microsoft.com/en-us/library/aa363788.aspx
269 
270  DWORD share = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
271 
272  HANDLE hfile1
273  = CreateFile (f1, 0, share, 0, OPEN_EXISTING,
274  f1_is_dir ? FILE_FLAG_BACKUP_SEMANTICS : 0, 0);
275 
276  if (hfile1 != INVALID_HANDLE_VALUE)
277  {
278  HANDLE hfile2
279  = CreateFile (f2, 0, share, 0, OPEN_EXISTING,
280  f2_is_dir ? FILE_FLAG_BACKUP_SEMANTICS : 0, 0);
281 
282  if (hfile2 != INVALID_HANDLE_VALUE)
283  {
284  BY_HANDLE_FILE_INFORMATION hfi1;
285  BY_HANDLE_FILE_INFORMATION hfi2;
286 
287  if (GetFileInformationByHandle (hfile1, &hfi1)
288  && GetFileInformationByHandle (hfile2, &hfi2))
289  {
290  retval = (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber
291  && hfi1.nFileIndexHigh == hfi2.nFileIndexHigh
292  && hfi1.nFileIndexLow == hfi2.nFileIndexLow);
293  }
294 
295  CloseHandle (hfile2);
296  }
297 
298  CloseHandle (hfile1);
299  }
300 
301  return retval;
302 
303 #else
304 
305  // POSIX Code
306 
307  octave::sys::file_stat fs_file1 (file1);
308  octave::sys::file_stat fs_file2 (file2);
309 
310  return (fs_file1 && fs_file2
311  && fs_file1.ino () == fs_file2.ino ()
312  && fs_file1.dev () == fs_file2.dev ());
313 
314 #endif
315 }
316 
317 void
319 {
320  // Use a function from libgomp to force loading of OpenMP library.
321  // Otherwise, a dynamically loaded library making use of OpenMP such
322  // as GraphicsMagick will segfault on exit (bug #41699).
323 #if defined (HAVE_OMP_GET_NUM_THREADS)
324  omp_get_num_threads ();
325 #endif
326 
327 #if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
328  BSD_init ();
329 #elif defined (__MINGW32__)
330  MINGW_init ();
331 #elif defined (_MSC_VER)
332  MSVC_init ();
333 #endif
334 }
335 
336 void
338 {
339 #if defined (OCTAVE_USE_WINDOWS_API)
340  // Let us fail immediately without displaying any dialog.
341  SetProcessShutdownParameters (0x280, SHUTDOWN_NORETRY);
342 #endif
343 }
344 
345 // Set terminal in raw mode. From less-177.
346 //
347 // Change terminal to "raw mode", or restore to "normal" mode.
348 // "Raw mode" means
349 // 1. An outstanding read will complete on receipt of a single keystroke.
350 // 2. Input is not echoed.
351 // 3. On output, \n is mapped to \r\n.
352 // 4. \t is NOT expanded into spaces.
353 // 5. Signal-causing characters such as ctrl-C (interrupt),
354 // etc. are NOT disabled.
355 // It doesn't matter whether an input \n is mapped to \r, or vice versa.
356 
357 void
358 raw_mode (bool on, bool wait)
359 {
360  static bool curr_on = false;
361 
362  int tty_fd = STDIN_FILENO;
363  if (! octave_isatty_wrapper (tty_fd))
364  {
365  if (octave::application::interactive ()
366  && ! octave::application::forced_interactive ())
367  error ("stdin is not a tty!");
368  }
369 
370  if (on == curr_on)
371  return;
372 
373 #if defined (HAVE_TERMIOS_H)
374  {
375  struct termios s;
376  static struct termios save_term;
377 
378  if (on)
379  {
380  // Get terminal modes.
381 
382  tcgetattr (tty_fd, &s);
383 
384  // Save modes and set certain variables dependent on modes.
385 
386  save_term = s;
387 // ospeed = s.c_cflag & CBAUD;
388 // erase_char = s.c_cc[VERASE];
389 // kill_char = s.c_cc[VKILL];
390 
391  // Set the modes to the way we want them.
392 
393  s.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
394  s.c_oflag |= (OPOST | ONLCR);
395 #if defined (OCRNL)
396  s.c_oflag &= ~(OCRNL);
397 #endif
398 #if defined (ONOCR)
399  s.c_oflag &= ~(ONOCR);
400 #endif
401 #if defined (ONLRET)
402  s.c_oflag &= ~(ONLRET);
403 #endif
404  s.c_cc[VMIN] = (wait ? 1 : 0);
405  s.c_cc[VTIME] = 0;
406  }
407  else
408  {
409  // Restore saved modes.
410 
411  s = save_term;
412  }
413 
414  tcsetattr (tty_fd, wait ? TCSAFLUSH : TCSADRAIN, &s);
415  }
416 #elif defined (HAVE_TERMIO_H)
417  {
418  struct termio s;
419  static struct termio save_term;
420 
421  if (on)
422  {
423  // Get terminal modes.
424 
425  ioctl (tty_fd, TCGETA, &s);
426 
427  // Save modes and set certain variables dependent on modes.
428 
429  save_term = s;
430 // ospeed = s.c_cflag & CBAUD;
431 // erase_char = s.c_cc[VERASE];
432 // kill_char = s.c_cc[VKILL];
433 
434  // Set the modes to the way we want them.
435 
436  s.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
437  s.c_oflag |= (OPOST | ONLCR);
438 #if defined (OCRNL)
439  s.c_oflag &= ~(OCRNL);
440 #endif
441 #if defined (ONOCR)
442  s.c_oflag &= ~(ONOCR);
443 #endif
444 #if defined (ONLRET)
445  s.c_oflag &= ~(ONLRET);
446 #endif
447  s.c_cc[VMIN] = (wait ? 1 : 0);
448  }
449  else
450  {
451  // Restore saved modes.
452 
453  s = save_term;
454  }
455 
456  ioctl (tty_fd, TCSETAW, &s);
457  }
458 #elif defined (HAVE_SGTTY_H)
459  {
460  octave_unused_parameter (wait);
461 
462  struct sgttyb s;
463  static struct sgttyb save_term;
464 
465  if (on)
466  {
467  // Get terminal modes.
468 
469  ioctl (tty_fd, TIOCGETP, &s);
470 
471  // Save modes and set certain variables dependent on modes.
472 
473  save_term = s;
474 // ospeed = s.sg_ospeed;
475 // erase_char = s.sg_erase;
476 // kill_char = s.sg_kill;
477 
478  // Set the modes to the way we want them.
479 
480  s.sg_flags |= CBREAK;
481  s.sg_flags &= ~(ECHO);
482  }
483  else
484  {
485  // Restore saved modes.
486 
487  s = save_term;
488  }
489 
490  ioctl (tty_fd, TIOCSETN, &s);
491  }
492 #else
493 
494  octave_unused_parameter (wait);
495 
496  warn_disabled_feature ("", "raw mode console I/O");
497 
498  // Make sure the current mode doesn't toggle.
499  on = curr_on;
500 #endif
501 
502  curr_on = on;
503 }
504 
505 FILE *
506 octave_popen (const char *command, const char *mode)
507 {
508 #if defined (__MINGW32__) || defined (_MSC_VER)
509  if (mode && mode[0] && ! mode[1])
510  {
511  // Use binary mode on Windows if unspecified
512  char tmode[3] = {mode[0], 'b', '\0'};
513 
514  return _popen (command, tmode);
515  }
516  else
517  return _popen (command, mode);
518 #else
519  return popen (command, mode);
520 #endif
521 }
522 
523 int
525 {
526 #if defined (__MINGW32__) || defined (_MSC_VER)
527  return _pclose (f);
528 #else
529  return pclose (f);
530 #endif
531 }
532 
533 // Read one character from the terminal.
534 
535 int
536 octave_kbhit (bool wait)
537 {
538 #if defined (HAVE__KBHIT) && defined (HAVE__GETCH)
539  // This essentially means we are on a Windows system.
540  int c;
541 
542  if (wait)
543  c = _getch ();
544  else
545  c = (! _kbhit ()) ? 0 : _getch ();
546 
547 #else
548  raw_mode (true, wait);
549 
550  // Get current handler.
551  octave::interrupt_handler saved_interrupt_handler
553 
554  // Restore it, disabling system call restarts (if possible) so the
555  // read can be interrupted.
556 
557  octave::set_interrupt_handler (saved_interrupt_handler, false);
558 
559  int c = std::cin.get ();
560 
561  if (std::cin.fail () || std::cin.eof ())
562  std::cin.clear ();
563 
564  // Restore it, enabling system call restarts (if possible).
565  octave::set_interrupt_handler (saved_interrupt_handler, true);
566 
567  raw_mode (false, true);
568 #endif
569 
570  return c;
571 }
572 
575 {
576 #if defined (OCTAVE_USE_WINDOWS_API)
577 
579 
580 #if defined (P_tmpdir)
581  retval = P_tmpdir;
582 #endif
583 
584  // Apparently some versions of MinGW and MSVC either don't define
585  // P_tmpdir, or they define it to a single backslash, neither of which
586  // is particularly helpful.
587 
588  if (retval.empty () || retval == R"(\)")
589  {
590  retval = octave::sys::env::getenv ("TEMP");
591 
592  if (retval.empty ())
594 
595  if (retval.empty ())
596  retval = R"(c:\temp)";
597  }
598 
599  return retval;
600 
601 #elif defined (P_tmpdir)
602 
603  return P_tmpdir;
604 
605 #else
606 
607  return "/tmp";
608 
609 #endif
610 }
611 
612 DEFUN (clc, , ,
613  doc: /* -*- texinfo -*-
614 @deftypefn {} {} clc ()
615 @deftypefnx {} {} home ()
616 Clear the terminal screen and move the cursor to the upper left corner.
617 @end deftypefn */)
618 {
619  bool skip_redisplay = true;
620 
621  octave::command_editor::clear_screen (skip_redisplay);
622 
623  return ovl ();
624 }
625 
626 DEFALIAS (home, clc);
627 
628 DEFUN (getenv, args, ,
629  doc: /* -*- texinfo -*-
630 @deftypefn {} {} getenv (@var{var})
631 Return the value of the environment variable @var{var}.
632 
633 For example,
634 
635 @example
636 getenv ("PATH")
637 @end example
638 
639 @noindent
640 returns a string containing the value of your path.
641 @seealso{setenv, unsetenv}
642 @end deftypefn */)
643 {
644  if (args.length () != 1)
645  print_usage ();
646 
647  std::string name = args(0).string_value ();
648 
649  return ovl (octave::sys::env::getenv (name));
650 }
651 
652 /*
653 %!assert (ischar (getenv ("OCTAVE_HOME")))
654 */
655 
656 DEFUN (setenv, args, ,
657  doc: /* -*- texinfo -*-
658 @deftypefn {} {} setenv (@var{var}, @var{value})
659 @deftypefnx {} {} setenv (@var{var})
660 @deftypefnx {} {} putenv (@dots{})
661 Set the value of the environment variable @var{var} to @var{value}.
662 
663 If no @var{value} is specified then the variable will be assigned the null
664 string.
665 @seealso{unsetenv, getenv}
666 @end deftypefn */)
667 {
668  int nargin = args.length ();
669 
671  print_usage ();
672 
673  std::string var = args(0).xstring_value ("setenv: VAR must be a string");
674 
675  std::string val = (nargin == 2
676  ? args(1).xstring_value ("setenv: VALUE must be a string")
677  : "");
678 
680 
681  return ovl ();
682 }
683 
684 DEFALIAS (putenv, setenv);
685 
686 /*
687 %!test
688 %! setenv ("dummy_variable_that_cannot_matter", "foobar");
689 %! assert (getenv ("dummy_variable_that_cannot_matter"), "foobar");
690 %! unsetenv ("dummy_variable_that_cannot_matter");
691 %! assert (getenv ("dummy_variable_that_cannot_matter"), "");
692 */
693 
694 DEFUN (unsetenv, args, ,
695  doc: /* -*- texinfo -*-
696 @deftypefn {} {@var{status} =} unsetenv (@var{var})
697 Delete the environment variable @var{var}.
698 
699 Return 0 if the variable was deleted, or did not exist, and -1 if an error
700 occurred.
701 @seealso{setenv, getenv}
702 @end deftypefn */)
703 {
704  if (args.length () != 1)
705  print_usage ();
706 
707  std::string tmp = args(0).string_value ();
708 
709  return ovl (octave_unsetenv_wrapper (tmp.c_str ()));
710 }
711 
712 /*
713 ## Test for unsetenv is in setenv test
714 */
715 
716 #if defined (OCTAVE_USE_WINDOWS_API)
717 
718 static void
719 reg_close_key_wrapper (HKEY key)
720 {
721  RegCloseKey (key);
722 }
723 
724 LONG
725 get_regkey_value (HKEY h_rootkey, const std::string subkey,
727 {
728  LONG result;
729  HKEY h_subkey;
730 
731  result = RegOpenKeyExA (h_rootkey, subkey.c_str (), 0, KEY_READ, &h_subkey);
732  if (result != ERROR_SUCCESS)
733  return result;
734 
736 
737  frame.add_fcn (reg_close_key_wrapper, h_subkey);
738 
739  DWORD length = 0;
740  result = RegQueryValueExA (h_subkey, name.c_str (), nullptr, nullptr, nullptr,
741  &length);
742  if (result != ERROR_SUCCESS)
743  return result;
744 
745  DWORD type = 0;
746  OCTAVE_LOCAL_BUFFER (BYTE, data, length);
747  result = RegQueryValueExA (h_subkey, name.c_str (), nullptr, &type, data,
748  &length);
749  if (result != ERROR_SUCCESS)
750  return result;
751 
752  if (type == REG_DWORD)
753  value = octave_int32 (*data);
754  else if (type == REG_SZ || type == REG_EXPAND_SZ)
755  value = string_vector (reinterpret_cast<char *> (data));
756 
757  return result;
758 }
759 
760 LONG
761 get_regkey_names (HKEY h_rootkey, const std::string subkey,
762  std::list<std::string> &fields)
763 {
764  LONG retval;
765  HKEY h_subkey;
766 
767  fields.clear ();
768 
769  retval = RegOpenKeyEx (h_rootkey, subkey.c_str (), 0, KEY_READ, &h_subkey);
770  if (retval != ERROR_SUCCESS)
771  return retval;
772 
773  DWORD idx = 0;
774  const int MAX_VALUE_NAME_SIZE = 32766;
775  char value_name[MAX_VALUE_NAME_SIZE+1];
776  DWORD value_name_size = MAX_VALUE_NAME_SIZE;
777 
778  while (true)
779  {
780  retval = RegEnumValue (h_subkey, idx, value_name, &value_name_size,
781  nullptr, nullptr, nullptr, nullptr);
782  if (retval != ERROR_SUCCESS)
783  break;
784  fields.push_back (value_name);
785  value_name_size = MAX_VALUE_NAME_SIZE;
786  idx++;
787  }
788 
789  if (retval == ERROR_NO_MORE_ITEMS)
790  retval = ERROR_SUCCESS;
791 
792  RegCloseKey (h_subkey);
793 
794  return retval;
795 }
796 #endif
797 
798 DEFUN (winqueryreg, args, ,
799  doc: /* -*- texinfo -*-
800 @deftypefn {} {@var{value} =} winqueryreg (@var{rootkey}, @var{subkey}, @var{valuename})
801 @deftypefnx {} {@var{value} =} winqueryreg (@var{rootkey}, @var{subkey})
802 @deftypefnx {} {@var{names} =} winqueryreg (@code{"name"}, @var{rootkey}, @var{subkey})
803 
804 Query names or value from the Windows registry.
805 
806 On Windows, return the value of the registry key @var{subkey} from the root key
807 @var{rootkey}. You can specify the name of the queried registry value with the
808 optional argument @var{valuename}. Otherwise, if called with only two
809 arguments or @var{valuename} is empty, then the default value of @var{subkey}
810 is returned. If the registry value is of type @nospell{@qcode{"REG_DWORD"}}
811 then @var{value} is of class int32. If the value is of the type
812 @nospell{@qcode{"REG_SZ"}} or @nospell{@qcode{"REG_EXPAND_SZ"}} a string is
813 returned.
814 
815 If the first argument is @qcode{"name"}, a cell array of strings with the names
816 of the values at that key is returned.
817 
818 The variable @var{rootkey} must be a string with a valid root key identifier:
819 
820 @table @asis
821 @item @nospell{HKCR}
822 @itemx @nospell{HKEY_CLASSES_ROOT}
823 
824 @item @nospell{HKEY_CURRENT_CONFIG}
825 
826 @item @nospell{HKCU}
827 @itemx @nospell{HKEY_CURRENT_USER}
828 
829 @item @nospell{HKLM}
830 @itemx @nospell{HKEY_LOCAL_MACHINE}
831 
832 
833 @item @nospell{HKU}
834 @itemx @nospell{HKEY_USERS}
835 
836 
837 @item @nospell{HKEY_PERFORMANCE_DATA}
838 
839 @end table
840 
841 Examples:
842 
843 Get a list of value names at the key @nospell{@qcode{'HKCU\Environment'}}:
844 
845 @example
846 @group
847 @var{valuenames} = winqueryreg ("name", "HKEY_CURRENT_USER", ...
848  "Environment");
849 @end group
850 @end example
851 
852 For each @var{valuenames}, display the value:
853 
854 @example
855 @group
856 for @var{k} = 1:numel (@var{valuenames})
857  @var{val} = winqueryreg ("HKEY_CURRENT_USER", "Environment", ...
858  @var{valuenames}@{@var{k}@});
859  @var{str} = sprintf ("%s = %s", @var{valuenames}@{@var{k}@}, num2str (@var{val}));
860  disp (@var{str});
861 endfor
862 @end group
863 @end example
864 
865 On non-Windows platforms this function fails with an error.
866 @end deftypefn */)
867 {
868 #if defined (OCTAVE_USE_WINDOWS_API)
869  if ((args.length () < 2) || (args.length () > 3))
870  print_usage ();
871 
872  // Input check
873  std::string rootkey_name =
874  args(0).xstring_value ("winqueryreg: the first argument must be 'name' "
875  "or a valid ROOTKEY identifier");
876  std::string subkey_name = "";
877  std::string value_name = "";
878  bool get_names = false;
879  if (rootkey_name.compare ("name") == 0)
880  {
881  if (args.length () < 3)
882  error ("winqueryreg: if the first argument is 'name', "
883  "ROOTKEY and SUBKEY must be given");
884  get_names = true;
885  rootkey_name =
886  args(1).xstring_value ("winqueryreg: ROOTKEY must be a string");
887  subkey_name =
888  args(2).xstring_value ("winqueryreg: SUBKEY must be a string");
889  }
890  else
891  {
892  subkey_name =
893  args(1).xstring_value ("winqueryreg: SUBKEY must be a string");
894  if (args.length () == 3)
895  value_name =
896  args(2).xstring_value ("winqueryreg: VALUENAME must be a string");
897  }
898 
899  // Get rootkey handle
900  HKEY h_rootkey;
901  if (rootkey_name == "HKEY_CLASSES_ROOT" || rootkey_name == "HKCR")
902  h_rootkey = HKEY_CLASSES_ROOT;
903  else if (rootkey_name == "HKEY_CURRENT_CONFIG")
904  h_rootkey = HKEY_CURRENT_CONFIG;
905  else if (rootkey_name == "HKEY_CURRENT_USER" || rootkey_name == "HKCU")
906  h_rootkey = HKEY_CURRENT_USER;
907  else if (rootkey_name == "HKEY_LOCAL_MACHINE" || rootkey_name == "HKLM")
908  h_rootkey = HKEY_LOCAL_MACHINE;
909  else if (rootkey_name == "HKEY_PERFORMANCE_DATA")
910  h_rootkey = HKEY_PERFORMANCE_DATA;
911  else if (rootkey_name == "HKEY_USERS" || rootkey_name == "HKU")
912  h_rootkey = HKEY_USERS;
913  else
914  error ("winqueryreg: ROOTKEY is not a valid root key identifier");
915 
916  if (get_names)
917  {
918  std::list<std::string> fields;
919 
920  LONG retval = get_regkey_names (h_rootkey, subkey_name, fields);
921  if (retval != ERROR_SUCCESS)
922  error ("winqueryreg: error %d reading names from registry", retval);
923 
924  Cell fieldnames (dim_vector (1, fields.size ()));
925  size_t i;
926  std::list<std::string>::const_iterator it;
927  for (i = 0, it = fields.begin (); it != fields.end (); ++it, ++i)
928  fieldnames(i) = *it;
929 
930  return ovl (fieldnames);
931  }
932  else
933  {
934  octave_value key_val;
935  LONG retval = get_regkey_value (h_rootkey, subkey_name, value_name,
936  key_val);
937  if (retval == ERROR_FILE_NOT_FOUND)
938  error ("winqueryreg: no value found for '%s' at %s\\%s.",
939  value_name.c_str (), rootkey_name.c_str (),
940  subkey_name.c_str ());
941  if (retval != ERROR_SUCCESS)
942  error ("winqueryreg: error %d reading the specified key", retval);
943 
944  return ovl (key_val);
945  }
946 #else
947 
948  octave_unused_parameter (args);
949 
950  error ("winqueryreg: function is only supported on Windows platforms");
951 
952 #endif
953 }
954 
955 /*
956 %!testif ; ispc ()
957 %! assert (ischar (winqueryreg ("HKEY_LOCAL_MACHINE",
958 %! 'SOFTWARE\Microsoft\Windows\CurrentVersion',
959 %! "ProgramFilesDir")));
960 %!testif ; ispc ()
961 %! assert (isa (winqueryreg ("HKEY_LOCAL_MACHINE",
962 %! 'SYSTEM\CurrentControlSet\Control\FileSystem',
963 %! "Win31FileSystem"), "int32"));
964 %!testif ; ispc ()
965 %! assert (iscellstr (winqueryreg ("name", "HKEY_LOCAL_MACHINE",
966 %! 'SOFTWARE\Microsoft\Windows\CurrentVersion')));
967 %!testif ; ispc ()
968 %! fail ('winqueryreg (1, ''SOFTWARE\Microsoft\Windows\CurrentVersion'')',
969 %! "first argument must be 'name' or a valid ROOTKEY identifier");
970 %!testif ; ispc ()
971 %! fail ('winqueryreg ("HKEY_LOCAL_MACHINE", 1)', "SUBKEY must be a string");
972 %!testif ; ispc ()
973 %! fail (['winqueryreg ("HKEY_LOCAL_MACHINE", ', ...
974 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'', 1)'],
975 %! "VALUENAME must be a string");
976 %!testif ; ispc ()
977 %! fail (['winqueryreg ("FOO", ', ...
978 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'')'],
979 %! "ROOTKEY is not a valid root key identifier");
980 %!testif ; ispc ()
981 %! fail ('winqueryreg ("HKEY_LOCAL_MACHINE", ''FOO\bar'')',
982 %! "no value found for");
983 %!testif ; ispc ()
984 %! fail (['winqueryreg ("HKEY_LOCAL_MACHINE", ', ...
985 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'', "foo")'],
986 %! "no value found for");
987 %!testif ; ispc ()
988 %! fail ('winqueryreg ("name", "HKEY_LOCAL_MACHINE")',
989 %! "if the first argument is 'name', ROOTKEY and SUBKEY must be given");
990 %!testif ; ispc ()
991 %! fail (['winqueryreg ("name", 1, ', ...
992 %! '''SOFTWARE\Microsoft\Windows\CurrentVersion'')'],
993 %! "ROOTKEY must be a string");
994 %!testif ; ispc ()
995 %! fail ('winqueryreg ("name", "HKEY_LOCAL_MACHINE", 1)',
996 %! "SUBKEY must be a string");
997 */
998 
999 // FIXME: perhaps kbhit should also be able to print a prompt?
1000 
1001 DEFUN (kbhit, args, ,
1002  doc: /* -*- texinfo -*-
1003 @deftypefn {} {} kbhit ()
1004 @deftypefnx {} {} kbhit (1)
1005 Read a single keystroke from the keyboard.
1006 
1007 If called with an argument, don't wait for a keypress.
1008 
1009 For example,
1010 
1011 @example
1012 x = kbhit ();
1013 @end example
1014 
1015 @noindent
1016 will set @var{x} to the next character typed at the keyboard as soon as
1017 it is typed.
1018 
1019 @example
1020 x = kbhit (1);
1021 @end example
1022 
1023 @noindent
1024 is identical to the above example, but doesn't wait for a keypress,
1025 returning the empty string if no key is available.
1026 @seealso{input, pause}
1027 @end deftypefn */)
1028 {
1029  // FIXME: add timeout and default value args?
1030 
1031  Fdrawnow ();
1032 
1033  int c = octave_kbhit (args.length () == 0);
1034 
1035  if (c == -1)
1036  c = 0;
1037 
1038  char s[2] = { static_cast<char> (c), '\0' };
1039 
1040  return octave_value (s);
1041 }
1042 
1043 DEFUN (pause, args, ,
1044  doc: /* -*- texinfo -*-
1045 @deftypefn {} {} pause ()
1046 @deftypefnx {} {} pause (@var{n})
1047 Suspend the execution of the program for @var{n} seconds.
1048 
1049 If invoked without an input arguments then the program is suspended until a
1050 character is typed.
1051 
1052 @var{n} is a positive real value and may be a fraction of a second,
1053 for example:
1054 
1055 @example
1056 @group
1057 tic; pause (0.05); toc
1058  @print{} Elapsed time is 0.05039 seconds.
1059 @end group
1060 @end example
1061 
1062 The following example prints a message and then waits 5 seconds before
1063 clearing the screen.
1064 
1065 @example
1066 @group
1067 disp ("wait please...");
1068 pause (5);
1069 clc;
1070 @end group
1071 @end example
1072 
1073 @seealso{kbhit}
1074 @end deftypefn */)
1075 {
1076  int nargin = args.length ();
1077 
1078  if (nargin > 1)
1079  print_usage ();
1080 
1081  if (nargin == 1)
1082  {
1083  double dval = args(0).double_value ();
1084 
1085  if (octave::math::isnan (dval))
1086  warning ("pause: NaN is an invalid delay");
1087  else
1088  {
1089  Fdrawnow ();
1090 
1091  if (octave::math::isinf (dval))
1092  {
1094  octave_kbhit ();
1095  }
1096  else
1097  octave_sleep (dval);
1098  }
1099  }
1100  else
1101  {
1102  Fdrawnow ();
1104  octave_kbhit ();
1105  }
1106 
1107  return ovl ();
1108 }
1109 
1110 /*
1111 %!test
1112 %! pause (1);
1113 
1114 %!error (pause (1, 2))
1115 */
1116 
1117 // FIXME: maybe this should only return 1 if IEEE floating
1118 // point functions really work.
1119 
1120 DEFUN (isieee, , ,
1121  doc: /* -*- texinfo -*-
1122 @deftypefn {} {} isieee ()
1123 Return true if your computer @emph{claims} to conform to the IEEE standard
1124 for floating point calculations.
1125 
1126 No actual tests are performed.
1127 @end deftypefn */)
1128 {
1131 
1134 }
1135 
1136 /*
1137 %!assert (islogical (isieee ()))
1138 */
1139 
1141  doc: /* -*- texinfo -*-
1142 @deftypefn {} {} native_float_format ()
1143 Return the native floating point format as a string.
1144 @end deftypefn */)
1145 {
1148 
1150 }
1151 
1152 /*
1153 %!assert (ischar (native_float_format ()))
1154 */
1155 
1156 DEFUN (tilde_expand, args, ,
1157  doc: /* -*- texinfo -*-
1158 @deftypefn {} {} tilde_expand (@var{string})
1159 @deftypefnx {} {} tilde_expand (@var{cellstr})
1160 Perform tilde expansion on @var{string}.
1161 
1162 If @var{string} begins with a tilde character, (@samp{~}), all of the
1163 characters preceding the first slash (or all characters, if there is no
1164 slash) are treated as a possible user name, and the tilde and the following
1165 characters up to the slash are replaced by the home directory of the named
1166 user. If the tilde is followed immediately by a slash, the tilde is
1167 replaced by the home directory of the user running Octave.
1168 
1169 If the input is a cell array of strings @var{cellstr} then tilde expansion
1170 is performed on each string element.
1171 
1172 Examples:
1173 
1174 @example
1175 @group
1176 tilde_expand ("~joeuser/bin")
1177  @result{} "/home/joeuser/bin"
1178 tilde_expand ("~/bin")
1179  @result{} "/home/jwe/bin"
1180 @end group
1181 @end example
1182 @end deftypefn */)
1183 {
1184  if (args.length () != 1)
1185  print_usage ();
1186 
1187  octave_value arg = args(0);
1188 
1189  string_vector sv = arg.xstring_vector_value ("tilde_expand: argument must be char or cellstr object");
1190 
1192 
1193  if (arg.iscellstr ())
1194  return ovl (Cell (arg.dims (), sv));
1195  else
1196  return ovl (sv);
1197 }
1198 
1199 /*
1200 %!test
1201 %! home = get_home_directory ();
1202 %! assert (tilde_expand ("~/foobar"), [home "/foobar"]);
1203 %! assert (tilde_expand ("/foo/bar"), "/foo/bar");
1204 %! assert (tilde_expand ("foo/bar"), "foo/bar");
1205 */
1206 
1207 DEFUN (get_home_directory, , ,
1208  doc: /* -*- texinfo -*-
1209 @deftypefn {} {@var{homedir} =} get_home_directory ()
1210 Return the current home directory.
1211 
1212 On most systems, this is equivalent to @code{getenv ("HOME")}. On Windows
1213 systems, if the environment variable @env{HOME} is not set then it is
1214 equivalent to
1215 @code{fullfile (getenv ("HOMEDRIVE"), getenv ("HOMEPATH"))}
1216 @seealso{getenv}
1217 @end deftypefn */)
1218 {
1220 }
1221 
1222 /*
1223 %!test
1224 %! if (! ispc ())
1225 %! assert (get_home_directory (), getenv ("HOME"));
1226 %! endif
1227 */
1228 
1229 DEFUN (__blas_version__, , ,
1230  doc: /* -*- texinfo -*-
1231 @deftypefn {} {} __blas_version__ ()
1232 Undocumented internal function.
1233 @end deftypefn */)
1234 {
1235  return ovl (octave::sys::blas_version ());
1236 }
1237 
1238 DEFUN (__lapack_version__, , ,
1239  doc: /* -*- texinfo -*-
1240 @deftypefn {} {} __lapack_version__ ()
1241 Undocumented internal function.
1242 @end deftypefn */)
1243 {
1244  return ovl (octave::sys::lapack_version ());
1245 }
scalar structure containing the fields
Definition: ov-struct.cc:1736
OCTINTERP_API void octave_sleep(double seconds)
Definition: Cell.h:37
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
static void putenv(const std::string &name, const std::string &value)
Definition: oct-env.cc:242
FILE * octave_popen(const char *command, const char *mode)
Definition: sysdep.cc:506
void raw_mode(bool on, bool wait)
Definition: sysdep.cc:358
int octave_pclose(FILE *f)
Definition: sysdep.cc:524
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode fieldnames
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
void set_application_id(void)
Definition: sysdep.cc:175
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6348
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:276
int octave_kbhit(bool wait)
Definition: sysdep.cc:536
void flush_stdout(void)
Definition: pager.cc:464
void add_fcn(void(*fcn)(void))
bool isnan(bool)
Definition: lo-mappers.h:187
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
bool isinf(double x)
Definition: lo-mappers.h:225
#define STDIN_FILENO
Definition: sysdep.cc:88
octave::mach_info::float_format flt_fmt
Definition: load-save.cc:736
to define functions rather than attempting to enter them directly on the command line The block of commands is executed as soon as you exit the editor To avoid executing any simply delete all the lines from the buffer before leaving the editor When invoked with no edit the previously executed command
Definition: oct-hist.cc:587
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
void sysdep_cleanup(void)
Definition: sysdep.cc:337
endfor nd group nd example On non Windows platforms this function fails with an error nd deftypefn * error("winqueryreg: function is only supported on Windows platforms")
s
Definition: file-io.cc:2729
pause(0.05)
ino_t ino(void) const
Definition: file-stat.h:117
virtual octave_value get(bool all=false) const
Definition: graphics.in.h:2466
octave_value arg
Definition: pr-output.cc:3244
static std::string getenv(const std::string &name)
Definition: oct-env.cc:235
std::string bin_dir(void)
Definition: defaults.cc:273
bool iscellstr(void) const
Definition: ov.h:543
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition: defun.h:211
double h
Definition: graphics.cc:11808
nd deftypefn *std::string name
Definition: sysdep.cc:647
int octave_isatty_wrapper(int fd)
static std::string get_home_directory(void)
Definition: oct-env.cc:143
bool same_file_internal(const std::string &file1, const std::string &file2)
Definition: sysdep.cc:255
return ovl(octave::sys::env::getenv(name))
float_format native_float_format(void)
Definition: mach-info.cc:62
dim_vector dims(void) const
Definition: ov.h:469
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:314
double tmp
Definition: data.cc:6252
octave_value retval
Definition: data.cc:6246
clc
Definition: sysdep.cc:1074
end example noindent will set var
Definition: sysdep.cc:1027
OCTAVE_EXPORT octave_value_list Fsystem(const octave_value_list &args, int nargout) ar
Definition: toplev.cc:236
idx type
Definition: ov.cc:3114
static bool prefer_env_winsize(bool)
Definition: cmd-edit.cc:1612
interrupt_handler ignore_interrupts(void)
Definition: sighandlers.cc:334
std::string lapack_version(void)
Definition: lo-sysinfo.cc:154
With real return the complex result
Definition: data.cc:3260
void warning(const char *fmt,...)
Definition: error.cc:801
octave::unwind_protect frame
Definition: graphics.cc:12190
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
defaults to zero A value of zero computes the digamma a value the trigamma and so on The digamma function is defined
Definition: psi.cc:68
int octave_unsetenv_wrapper(const char *name)
interrupt_handler set_interrupt_handler(const volatile interrupt_handler &h, bool restart_syscalls)
Definition: sighandlers.cc:345
std::string blas_version(void)
Definition: lo-sysinfo.cc:42
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:41
args.length() nargin
Definition: file-io.cc:589
string_vector xstring_vector_value(const char *fmt,...) const
for i
Definition: data.cc:5264
std::string get_P_tmpdir(void)
Definition: sysdep.cc:574
dev_t dev(void) const
Definition: file-stat.h:118
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
octave_int< int32_t > octave_int32
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
nd group nd example For each display the value
Definition: sysdep.cc:866
more on
Definition: toplev.cc:236
void sysdep_init(void)
Definition: sysdep.cc:318
std::string float_format_as_string(float_format flt_fmt)
Definition: mach-info.cc:102
static void clear_screen(bool skip_redisplay=false)
Definition: cmd-edit.cc:1246